真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

HTTP中有哪些規(guī)范

這篇文章給大家介紹HTTP中有哪些規(guī)范,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。

成都創(chuàng)新互聯(lián)主要從事成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、網(wǎng)頁(yè)設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)靖西,10余年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來(lái)電咨詢建站服務(wù):13518219792

1.Referer

HTTP 標(biāo)準(zhǔn)把 Referrer 寫(xiě)成 Referer(少些了一個(gè) r),可以說(shuō)是計(jì)算機(jī)歷史上最著名的一個(gè)錯(cuò)別字了。

Referer 的主要作用是攜帶當(dāng)前請(qǐng)求的來(lái)源地址,常用在反爬蟲(chóng)和防盜鏈上。前段時(shí)間鬧的沸沸揚(yáng)揚(yáng)的新浪圖床掛圖事件,就是因?yàn)樾吕藞D床突然開(kāi)始檢查 HTTP Referer 頭,非新浪域名就不返回圖片,導(dǎo)致很多蹭流量的中小博客圖都掛了。

雖然 HTTP 標(biāo)準(zhǔn)里把 Referer 寫(xiě)錯(cuò)了,但是其它可以控制 Referer 的標(biāo)準(zhǔn)并沒(méi)有將錯(cuò)就錯(cuò)。

例如禁止網(wǎng)頁(yè)自動(dòng)攜帶 Referer 頭的 標(biāo)簽,相關(guān)關(guān)鍵字拼寫(xiě)就是正確的:

  

還有一個(gè)值得注意的是瀏覽器的網(wǎng)絡(luò)請(qǐng)求。從安全性和穩(wěn)定性上考慮,Referer 等請(qǐng)求頭在網(wǎng)絡(luò)請(qǐng)求時(shí),只能由瀏覽器控制,不能直接操作,我們只能通過(guò)一些屬性進(jìn)行控制。比如說(shuō) Fetch 函數(shù),我們可以通過(guò) referrer 和 referrerPolicy 控制,而它們的拼寫(xiě)也是正確的:

fetch('/page', {    headers: {      "Content-Type": "text/plain;charset=UTF-8"    },    referrer: "https://demo.com/anotherpage", // <-    referrerPolicy: "no-referrer-when-downgrade", // <-  });

一句話總結(jié):

凡是涉及到 Referrer 的,除了 HTTP 字段是錯(cuò)的,瀏覽器的相關(guān)配置字段拼寫(xiě)都是正確的。

二.「靈異」的空格

1.%20 還是 + ?

這個(gè)是個(gè)史詩(shī)級(jí)的大坑,我曾經(jīng)被這個(gè)協(xié)議沖突坑了一天。

開(kāi)始講解前先看個(gè)小測(cè)試,在瀏覽器里輸入 blank test( blank 和 test 間有個(gè)空格),我們看看瀏覽器如何處理的:

HTTP中有哪些規(guī)范

從動(dòng)圖可以看出瀏覽器把空格解析為一個(gè)加號(hào)「+」。

是不是感覺(jué)有些奇怪?我們?cè)僮鰝€(gè)測(cè)試,用瀏覽器提供的幾個(gè)函數(shù)試一下:

encodeURIComponent("blank test") // "blank%20test"  encodeURI("q=blank test")        // "q=blank%20test"  new URLSearchParams("q=blank test").toString() // "q=blank+test"

HTTP中有哪些規(guī)范

代碼是不會(huì)說(shuō)謊的,其實(shí)上面的結(jié)果都是正確的,encode 結(jié)果不一樣,是因?yàn)?URI 規(guī)范和 W3C 規(guī)范沖突了,才會(huì)搞出這種讓人疑惑的烏龍事件。

2.沖突的協(xié)議

我們首先看看 URI 中的保留字,這些保留字不參與編碼。保留字符一共有兩大類(lèi):

  •  gen-delims:: / ? # [ ] @

  •  sub-delims:! $ & ' ( ) * + , ; =

URI 的編碼規(guī)則也很簡(jiǎn)單,先把非限定范圍的字符轉(zhuǎn)為 16 進(jìn)制,然后前面加百分號(hào)。

空格這種不安全字符轉(zhuǎn)為十六進(jìn)制就是 0x20,前面再加上百分號(hào) % 就是 %20:

HTTP中有哪些規(guī)范

所以這時(shí)候再看 encodeURIComponent 和 encodeURI 的編碼結(jié)果,就是完全正確的。

既然空格轉(zhuǎn)為%20 是正確的,那轉(zhuǎn)為 + 是怎么回事?這時(shí)候我們就要了解一下 HTML form 表單的歷史。

早期的網(wǎng)頁(yè)沒(méi)有 AJAX 的時(shí)候,提交數(shù)據(jù)都是通過(guò) HTML 的 form 表單。form 表單的提交方法可以用 GET 也可以用 POST,大家可以在 MDN form 詞條上測(cè)試:

HTTP中有哪些規(guī)范

經(jīng)過(guò)測(cè)試我們可以看出表單提交的內(nèi)容中,空格都是轉(zhuǎn)為加號(hào)的,這種編碼類(lèi)型就是 application/x-www-form-urlencoded,在 WHATWG 規(guī)范里是這樣定義的:

HTTP中有哪些規(guī)范

到這里基本上就破案了,URLSearchParams 做 encode 的時(shí)候,就按這個(gè)規(guī)范來(lái)的。我找到了 URLSearchParams 的 Polyfill 代碼,里面就做了 %20 到 + 的映射:

replace = {      '!': '%21',      "'": '%27',      '(': '%28',      ')': '%29',      '~': '%7E',      '%20': '+', // <= 就是這個(gè)      '%00': '\x00'  }

規(guī)范里對(duì)這個(gè)編碼類(lèi)型還有解釋說(shuō)明:

The application/x-www-form-urlencoded format is in many ways an aberrant monstrosity, the result of many years of implementation accidents and compromises leading to a set of requirements necessary for interoperability, but in no way representing good design practices. In particular, readers are cautioned to pay close attention to the twisted details involving repeated (and in some cases nested) conversions between character encodings and byte sequences. Unfortunately the format is in widespread use due to the prevalence of HTML forms.

這種編碼方式就不是個(gè)好的設(shè)計(jì),不幸的是隨著 HTML form 表單的普及,這種格式已經(jīng)推廣開(kāi)了

其實(shí)上面一大段句話就是一個(gè)意思:這玩意兒設(shè)計(jì)的就是 ?,但積重難返,大家還是忍一下吧

3.一句話總結(jié)

  •  URI 規(guī)范里,空格 encode 為 %20, application/x-www-form-urlencoded 格式里,空格 encode 為 +

  •  實(shí)際業(yè)務(wù)開(kāi)發(fā)時(shí),最好使用業(yè)內(nèi)成熟的 HTTP 請(qǐng)求庫(kù)封裝請(qǐng)求,這些雜活兒累活兒框架都干了;

  •  如果非要使用原生 AJAX 提交 application/x-www-form-urlencoded 格式的數(shù)據(jù),不要手動(dòng)拼接參數(shù),要用 URLSearchParams 處理數(shù)據(jù),這樣可以避免各種惡心的編碼沖突。

三.X-Forwarded-For 拿到的就是真實(shí) IP 嗎?

1.故事

在這個(gè)小節(jié)開(kāi)始前,我先講一個(gè)開(kāi)發(fā)中的小故事,可以加深一下大家對(duì)這個(gè)字段的理解。

前段時(shí)間要做一個(gè)和風(fēng)控相關(guān)的需求,需要拿到用戶的 IP,開(kāi)發(fā)后灰度了一小部分用戶,測(cè)試發(fā)現(xiàn)后臺(tái)日志里灰度的用戶 IP 全是異常的,哪有這么巧的事情。隨后測(cè)試發(fā)過(guò)來(lái)幾個(gè)異常 IP:

10.148.2.122  10.135.2.38  10.149.12.33  ...

一看 IP 特征我就明白了,這幾個(gè) IP 都是 10 開(kāi)頭的,屬于 A 類(lèi) IP 的私有 IP 范圍(10.0.0.0-10.255.255.255),后端拿到的肯定是代理服務(wù)器的 IP,而不是用戶的真實(shí) IP。

2.原理

HTTP中有哪些規(guī)范

現(xiàn)在有些規(guī)模的網(wǎng)站基本都不是單點(diǎn) Server 了,為了應(yīng)對(duì)更高的流量和更靈活的架構(gòu),應(yīng)用服務(wù)一般都是隱藏在代理服務(wù)器之后的,比如說(shuō) Nginx。

加入接入層后,我們就能比較容易的實(shí)現(xiàn)多臺(tái)服務(wù)器的負(fù)載均衡和服務(wù)升級(jí),當(dāng)然還有其他的好處,比如說(shuō)更好的內(nèi)容緩存和安全防護(hù),不過(guò)這些不是本文的重點(diǎn)就不展開(kāi)了。

網(wǎng)站加入代理服務(wù)器后,除了上面的幾個(gè)優(yōu)點(diǎn),同時(shí)引入了一些新的問(wèn)題。比如說(shuō)之前的單點(diǎn) Server,服務(wù)器是可以直接拿到用戶的 IP 的,加入代理層后,如上圖所示,(應(yīng)用)原始服務(wù)器拿到的是代理服務(wù)器的 IP,我前面講的故事的問(wèn)題就出在這里。

Web 開(kāi)發(fā)這么成熟的領(lǐng)域,肯定是有現(xiàn)成的解決辦法的,那就是 X-Forwarded-For 請(qǐng)求頭。

X-Forwarded-For 是一個(gè)事實(shí)標(biāo)準(zhǔn),雖然沒(méi)有寫(xiě)入 HTTP RFC 規(guī)范里,從普及程度上看其實(shí)可以算 HTTP 規(guī)范了。

這個(gè)標(biāo)準(zhǔn)是這樣定義的,每次代理服務(wù)器轉(zhuǎn)發(fā)請(qǐng)求到下一個(gè)服務(wù)器時(shí),要把代理服務(wù)器的 IP 寫(xiě)入 X-Forwarded-For 中,這樣在最末端的應(yīng)用服務(wù)收到請(qǐng)求時(shí),就會(huì)得到一個(gè) IP 列表:

X-Forwarded-For: client, proxy1, proxy2

因?yàn)?IP 是一個(gè)一個(gè)依次 push 進(jìn)去的,那么第一個(gè) IP 就是用戶的真實(shí) IP,取來(lái)用就好了。

但是,事實(shí)有這么簡(jiǎn)單嗎?

3.攻擊

從安全的角度上考慮,整個(gè)系統(tǒng)最不安全的就是人,用戶端都是最好攻破最好偽造的。有些用戶就開(kāi)始鉆協(xié)議的漏洞:X-Forwarded-For 是代理服務(wù)器添加的,如果我一開(kāi)始請(qǐng)求的 Header 頭里就加了 X-Forwarded-For ,不就騙過(guò)服務(wù)器了嗎?

1. 首先從客戶端發(fā)出請(qǐng)求,帶有 X-Forwarded-For 請(qǐng)求頭,里面寫(xiě)一個(gè)偽造的 IP:

X-Forwarded-For: fakeIP

2. 服務(wù)端第一層代理服務(wù)收到請(qǐng)求,發(fā)現(xiàn)已經(jīng)有 X-Forwarded-For,誤把這個(gè)請(qǐng)求當(dāng)成代理服務(wù)器,于是向這個(gè)字段追加了客戶端的真實(shí) IP:

X-Forwarded-For: fakeIP, client

3. 經(jīng)過(guò)幾層代理后,最終的服務(wù)器拿到的 Header 是這樣的:

X-Forwarded-For: fakeIP, client, proxy1, proxy2

要是按照取 X-Forwarded-For 第一個(gè) IP 的思路,你就著了攻擊者的道了,你拿到的是 fakeIP,而不是 client IP。

4.破招

服務(wù)端如何破招?上面三個(gè)步驟:

  •  第一步是客戶端造假,服務(wù)器無(wú)法介入

  •  第二步是代理服務(wù)器,可控,可防范

  •  第三步是應(yīng)用服務(wù)器,可控,可防范

第二步的破招我拿 Nginx 服務(wù)器舉例。

我們?cè)谧钔鈱拥?Nginx 上,對(duì) X-Forwarded-For 的配置如下:

proxy_set_header X-Forwarded-For $remote_addr;

什么意思呢?就是最外層代理服務(wù)器不信任客戶端的 X-Forwarded-For 輸入,直接覆蓋,而不是追加。

非最外層的 Nginx 服務(wù)器,我們配置:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

$proxy_add_x_forwarded_for 就是追加 IP 的意思。通過(guò)這招,就可以破除用戶端的偽造辦法。

第三步的破招思路也很容易,正常思路我們是取X-Forwarded-For 最左側(cè)的 IP,這次我們反其道而行之,從右邊數(shù),減去代理服務(wù)器的數(shù)目,那么剩下的 IP 里,最右邊的就是真實(shí) IP。

X-Forwarded-For: fakeIP, client, proxy1, proxy2

比如說(shuō)我們已知代理服務(wù)有兩層,從右向左數(shù),把 proxy1 和 proxy2 去掉,剩下的 IP 列表最右邊的就是真實(shí) IP。

相關(guān)思路和代碼實(shí)現(xiàn)可參考 Egg.js 前置代理模式。

5.一句話總結(jié)總結(jié)

通過(guò) X-Forwarded-For 獲取用戶真實(shí) IP 時(shí),最好不要取第一個(gè) IP,以防止用戶偽造 IP。

四.略顯混亂的分隔符

1.HTTP 標(biāo)準(zhǔn)

HTTP 請(qǐng)求頭字段如果涉及到多個(gè) value 時(shí),一般來(lái)說(shuō)每個(gè) value 間是用逗號(hào)「,」分隔的,就連非 RFC 標(biāo)準(zhǔn)的 X-Forwarded-For,也是用逗號(hào)分隔 value 的:

Accept-Encoding: gzip, deflate, br  cache-control: public, max-age=604800, s-maxage=43200  X-Forwarded-For: fakeIP, client, proxy1, proxy2

因?yàn)橐婚_(kāi)始用逗號(hào)分隔 value,后面想再用一個(gè)字段修飾 value 時(shí),分隔符就變成了分號(hào)「;」,最典型的請(qǐng)求頭就是 Accept 了:

//  q=0.9 修飾的是 application/xml,雖然它們之間用分號(hào)分隔  Accept: text/html, application/xml;q=0.9, */*;q=0.8

雖然 HTTP 協(xié)議易于閱讀,但是這個(gè)分隔符用的還是很不符合常識(shí)的。按常理來(lái)說(shuō),分號(hào)的斷句語(yǔ)氣是強(qiáng)于逗號(hào)的,但是在 HTTP 內(nèi)容協(xié)商的相關(guān)字段里卻是反過(guò)來(lái)的。這里的定義可以看 RFC 7231,寫(xiě)的還是比較清楚的。

2.Cookie 標(biāo)準(zhǔn)

和常規(guī)認(rèn)識(shí)不同,Cookie 其實(shí)不算 HTTP 標(biāo)準(zhǔn),定義 Cookie 的規(guī)范是 RFC 6265,所以分隔符規(guī)則也不一樣了。規(guī)范里定義的 Cookie 語(yǔ)法規(guī)則是這樣的:

cookie-header = "Cookie:" OWS cookie-string OWS  cookiecookie-string = cookie-pair *( ";" SP cookie-pair )

多個(gè) cookie 之間是用分號(hào)「;」分隔的,而不是逗號(hào)「,」。我隨便扒了個(gè)網(wǎng)站的 cookie,可見(jiàn)是用分號(hào)分隔的,這里需要特別注意一下:

HTTP中有哪些規(guī)范

關(guān)于HTTP中有哪些規(guī)范就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。


標(biāo)題名稱:HTTP中有哪些規(guī)范
分享URL:http://weahome.cn/article/ipogcd.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部