1. 程式人生 > 實用技巧 >HTTP協議學習總結

HTTP協議學習總結

前言

《圖解HTTP》中這樣描述HTTP在網路中的地位

Web使用一種名為HTTP(HyperText Transfer Protocol,超文字傳輸協議)的協議作為規範,完成從客戶端到伺服器等一系列運作流程。而協議是指規則的約定。可以說,Web是建立在HTTP協議上通訊的。

HTTP是不儲存狀態的協議,即無狀態協議,協議本身對於請求或響應之間的通訊狀態不進行儲存,因此連線雙方並不知道對方當前的身份和狀態。這也是Cookie技術產生的重要原因之一:客戶端的狀態管理。每次客戶端傳送HTTP請求,都會在請求報文中攜帶Cookie,作為服務端識別客戶端身份狀態的標識。

一. HTTP的版本演變

1.1 HTTP/1.1

HTTP最早在網頁中使用時1996年,那個時候只是使用一些較為簡單的網路請求,隨著網際網路的發展在1999年開始廣泛使用更為優化的HTTP/1.1。主要特點有:

  • 採用長連線:

    相較於HTTP/1.0的短連線(也被稱為序列連線、短輪詢)中美次HTTP通訊後都要斷開TCP連線,造成很大的通訊開銷。HTTP/1.1採用了只要雙方沒有提出斷開連線就會持久保持TCP連線狀態的長連線。這樣客戶端發起多個HTTP請求時就會減少TCP握手造成的網路資源和通訊時間的浪費。但是長連線會造成隊頭阻塞(Head-Of-LIne Blocking)造成頻寬無法唄充分利用。隊頭阻塞是指當順序傳送請求序列中的一個請求因為某種原因被阻塞時,在後面排隊的所有請求一併被阻塞。

  • Host頭處理:

    隨著虛擬主機技術的發展,在一臺物理伺服器上可以存在多個虛擬主機(Multi-homed Web Servers),並且他們共享一個IP地址。HTTP/1.1請求訊息和響應訊息包含Host頭部,以區分一個物理主機中的不同虛擬主機的域名。

  • 引入快取控制策略:

    Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供選擇的快取頭來控制快取策略。

  • 明文傳輸:

    HTTP/1.1在傳輸資料時,所有傳輸的內容都是明文,客戶端和伺服器端都無法驗證對方身份,這在一定程度上無法保證資料的安全性。

1.2 HTTP/2

2015年,HTTP/2 釋出。HTTP/2是現行HTTP協議(HTTP/1.x)的替代,但它由不是重寫,HTTP方法/狀態碼/語義都與HTTP/1.x一樣

HTTP/2基於SPDY,專注於效能,最大的目標是在使用者和網站之間只用一個連線。目前看來排名靠前的站點基本都實現了HTTP/2的部署。

在HTTP/2中,有兩個非常重要的概念,分別是幀(frame)流(steam),理解這兩個概念是理解HTTP/2重要特點--多路複用的前提。代表資料傳輸的最小單位,每個幀都有序列標識表明該幀數語哪個流。就是多個幀組成的資料流,每個資料流表示一個請求。

HTTP/2主要特點有:

  • 二進位制傳輸

    HTTP/2的傳輸資料量大幅減少,主要有兩個原因:以二進位制傳輸和Header壓縮。HTTP/2採用二進位制格式進行傳輸資料,而非HTTP/1.x裡純文字形式的報文,二進位制協議解析起來更加高效。

  • 頭部壓縮

    HTTP/1.x的請求和響應頭部帶有大量資訊,而且每次請求都需要重複傳送 ,用encoder來減少需要傳輸的頭部大小,通訊雙方各自cache一份頭部fields表,避免頭部重複傳送。

  • 多路複用

    多路複用就是在一個TCP連線中存在多條流,通過重新排序還原請求。多路複用允許併發的傳送多個請求,每個請求及該請求的響應不需要等待其他請求或響應,有效避免了隊頭阻塞問題。這樣,某個任務請求耗時嚴重,不會影響到其他連線的正常執行。多路複用並不是完美避免隊頭阻塞問題

    這是因為,TCP有特別的丟包重傳的機制,一旦HTTP/2出現丟包,丟失的包必須要等待重新傳輸確認,整個TCP連線都要開始等待重傳,那麼就會阻塞該TCP連線中的所有請求。這種情況下反而比HTTP/1.1延遲更高,因為HTTP/1.1是採用多個長連線進行通訊。

    如上圖所示,多路複用只通過一個TCP連線傳輸所有的請求資料。

  • 服務端推送(Server Push)

    HTTP/2 一定程度上改變了服務端傳統的“請求-應答”工作模式,服務端不再是完全被動的響應請求。如,把瀏覽器剛請求的HTML時候提前把可能會用到的JS、CSS等檔案發給客戶端,減少等待延遲。當然,客戶端是有權力選擇是否接收,如果發現客戶端已經快取了,那客戶端就會發送RST_STREAM幀來拒收。

  • 安全性提升

    出於相容考慮,HTTP/2依舊採用明文特點,不強制使用加密。

    但由於HTTPS已經是大勢所趨,主流的瀏覽器Chrome、Firefox都公開宣佈只支援加密的HTTP/2。所以通常來說HTTP/2都是使用“https”協議名,跑在TLS上面。

1.3 HTTP/3

Google在推出SPDY(就是HTTP/2基於的協議)的時候意識到了SPDY的問題是底層支撐的TCP協議造成的。主要有以下缺點:

  • TCP以及TCP+TLS建立連線的延時

    在建立TCP連線時,需要與伺服器進行三次握手進行確認連線,需要消耗1.5個RTT。

    HTTP/2還需要與TLS進行連線,大致需要1~2個RTT

    所以總的來說在傳輸資料前我們就得花掉3~4個RTT

  • TCP的隊頭阻塞並沒有解決

    前面我們提到不論是HTTP/1.x還是HTTP/2都並沒有完美解決隊頭阻塞問題。

這樣看來TCP才是最大的問題,所以就想到了另起爐灶。

Goole推出了基於UDP協議的QUIC協議,讓HTTP跑在QUIC上,而不是TCP上。HTTP over QUIC就是HTTP協議的下一個大版本,它在HTTP/2的基礎上又實現了質的飛躍,完美的解決了隊頭阻塞

以下是HTTP/3的一些特點:

  • 實現了類似TCP的流量控制、傳輸可靠性的功能

    雖然UDP不提供可靠性傳輸。但它提供了資料包重傳、擁塞控制以及其他一些TCP的特性。

  • 實現了快速握手功能

    由於底層協議是UDP,所以可以實現0-RTT或者1-RTT來建立連線,大大提升了速度。

  • 整合TLS加密功能

    使用的TLS1.3,減少了所花費的RTT

  • 多路複用

    實現了同一個物理連線上可以有多個獨立邏輯的資料流,實現了資料流的單獨傳輸,解決了TCP中的隊頭阻塞問題。

二. HTTP報文

用於HTTP協議互動的資訊被稱為HTTP報文。客戶端的HTTP報文叫做請求報文,服務端的HTTP報文叫做響應報文

請求報文是由:請求行(請求方法、協議版本)、請求首部(請求URI、客戶端資訊等)、內容實體(使用者資訊和資源資訊等)

響應報文是由:狀態行(狀態碼、協議版本)、響應首部(伺服器名稱、資源標識等)、內容實體(服務端返回的資源資訊等)

2.1 請求方法

方法 說明
GET GET請求會顯示請求指定的資源。一般來說GET方法應該只用於資料的讀取,而不應當用於會產生副作用的非冪等的操作中。它期望的應該是而且應該是安全的和冪等的。這裡的安全指的是,請求不會影響到資源的狀態。
POST POST請求會 向指定資源提交資料,請求伺服器進行處理,如:表單資料提交、檔案上傳等,請求資料會被包含在請求體中。POST方法是非冪等的方法,因為這個請求可能會建立新的資源或/和修改現有資源。
HEAD HEAD方法與GET方法一樣,都是向伺服器發出指定資源的請求。但是,伺服器在響應HEAD請求時不會回傳資源的內容部分,即:響應主體。這樣,我們可以不傳輸全部內容的情況下,就可以獲取伺服器的響應頭資訊。HEAD方法常被用於客戶端檢視伺服器的效能。
PUT PUT請求會身向指定資源位置上傳其最新內容,PUT方法是冪等的方法。通過該方法客戶端可以將指定資源的最新資料傳送給伺服器取代指定的資源的內容。
DELETE DELETE請求用於請求伺服器刪除所請求URI(統一資源識別符號,Uniform Resource Identifier)所標識的資源。DELETE請求後指定資源會被刪除,DELETE方法也是冪等的。
OPTIONS OPTIONS請求與HEAD類似,一般也是用於客戶端檢視伺服器的效能。 這個方法會請求伺服器返回該資源所支援的所有HTTP請求方法,該方法會用'*'來代替資源名稱,向伺服器傳送OPTIONS請求,可以測試伺服器功能是否正常。JavaScript的XMLHttpRequest物件進行CORS跨域資源共享時,就是使用OPTIONS方法傳送嗅探請求,以判斷是否有對指定資源的訪問許可權。

2.2 POST與GET的區別

  • 本質區別:

    本質上他們只是冪等非冪等的區別

  • 使用區別:

    1. GET使用URL,而POST使用body進行傳值。這主要是因為瀏覽器直接發出GET請求,只能由一個URL觸發。
    2. GET傳值有長度限制,POST傳值並沒有長度限制。這主要是因為瀏覽器對URL有著長度限制,而並非GET和POST的區別
    3. POST相較於GET更加安全,因為URL在位址列是可見的。但如果是使用HTTP作為底層協議,他們都是不安全的。
  • 什麼是冪等?

    從定義上看,HTTP方法中的冪等性是指:一次或多次請求某一個資源應當具有相同的副作用。

2.3 狀態碼

HTTP狀態碼是用以表示Web伺服器HTTP響應狀態的3位數字程式碼。

1XX 表示繼續傳送請求
100(Continue) 客戶端應繼續傳送請求
101(Switching Protocols) 需要切換協議
2xx 請求已成功被伺服器接收、理解並接受
200(OK) 請求已成功,請求所希望的響應頭或資料提將隨此響應返回
201(Accepted) 請求已經被實現,而且有一個新的資源已經依據請求的需要而建立。
202(Accpted) 伺服器已經接受請求,但尚未處理。比如post一個資源應當返回201,但由於效能原因未能立即建立,可以返回202
203(No Content) 伺服器成功處理請求,但不需要返回任何實體內容且不產生文件檢視變化
205(Reset Content) 伺服器成功處理裡請求,但不需要返回任何實體內容,與204區別是會重置文件檢視
206(Partial Content) HTTP協議允許分片傳輸。
3XX 代表客戶端需要採取進一步的操作才能完成請求
300(Multiple Choices) 客戶端請求實際指向多個資源的URL會返回這個狀態碼。比如說網站的中英文切換,300屬於客戶端驅動由客戶端發起請求,伺服器傳送可選項的列表,服務端返回300,可能彈出對話方塊讓使用者選擇。
301(Moved Permanently) 被請求的資源已經被永久的移動到新的位置,並且將來任何對此資源的引用都應使用本響應返回的URI
302(Found) 與301狀態碼類似,但是客戶端應該使用Location首部給出URL來臨時定位資源,將來的請求仍應使用舊的URL
303(See Other) 用來告知客戶端應該使用另一個URL來獲取資源
304(Not modified) 表示伺服器允許訪問資源,但文件的內容(自上次訪問以來或者根據請求的條件)並沒有改變。
4xx 客戶端錯誤
400(Bad Request) 請求報文中存在語法錯誤
401(Unauthorized) 當前請求需要使用者驗證,響應中會包含WWW-Authenticate欄位來詢問使用者的授權訊息,而客戶端下次請求需要提供包含Authorization頭的請求
403(Forbidden) 表示請求資源的訪問被伺服器拒絕,直接返回當前錯誤
404(Not Found) 請求得到的資源未在伺服器上被發現
5xx 這類狀態碼代表了伺服器在處理請求的過程中有錯誤或有異常狀態發生
500(Intenrnal Server Error) 程式碼出錯
501(Not Implemented) 表示伺服器不支援當前請求所需要的某個功能
503(Service Unavailable) 表明伺服器出於超載或正在停機維護
504(Gateway Time-out) 響應超時,通常被牆了

2.4 首部欄位

通用首部 作用(請求報文和響應報文都可能使用)
Cache-control 控制快取的行為:no-cache(強制向伺服器再次驗證)、no-store(不做任何快取)、max-age=1111(資源可快取最大時間)、public(客戶端、伺服器都可以利用快取)、private(代理伺服器不可用快取)
Connection 請求:close(告訴WEB伺服器或者代理伺服器,在完成本次請求的響應後,斷開連線,不要等待本次連線的後續請求了)。 keepalive(告訴WEB伺服器或者代理伺服器,在完成本次請求的響應後,保持連線,等待本次連線的後續請求)。 響應:close(連線已經關閉)。 keepalive(連線保持著,在等待本次連線的後續請求)。
Date 建立報文時間
via 代理伺服器的相關資訊,每經過一個代理伺服器就會新增相關資訊
Transfe-Encoding 傳輸編碼方式
Upgrade 要求客戶端使用的升級協議,需配合Connection:Upgrade一起使用
Warning 快取問題相關警告
請求首部 作用(請求報文專用)
Accept 能正確接收的媒體型別:application/jsontext/plain
Accept-Charset 能正確接收的字符集
Accept-Encoding 能正確接收的編碼格式列表
Accepte-Language 能正確接收的語言列表
Authorization 客戶端認證資訊,當客戶端接收到來自WEB伺服器的 WWW-Authenticate 響應時,用該頭部來回應自己的身份驗證資訊給WEB伺服器
Host 客戶端指定自己想訪問的WEB伺服器的域名/IP 地址和埠號。
If-Match 如果物件的 ETag 沒有改變,其實也就意味著物件沒有改變,才執行請求的動作。
If-Modified-Since 如果請求的物件在該指定的時間之後修改了,才執行的請求動作,否則返回304
User-Agent 瀏覽器表明自己的身份
響應首部 作用(響應報文專用)
Age 告知客戶端
Etag 資源標識,資源發生變化時標識也會發生變化
Location 伺服器告訴瀏覽器,試圖訪問的物件已經被移到別的位置上了
Server 伺服器表明自己是什麼軟體及版本資訊
proxy-Authenticate 代理伺服器響應瀏覽器,要求其提供代理身份驗證資訊
實體首部 作用(補充請求報文或響應報文相關資訊)
Allow 資源正確的請求方式:GETPOSTHEAD
Content-Encoding 內容使用的編碼格式
Content-Language 內容使用的語言
Content-Length 實體主體的長度
Content-Loaction 返回資料的備用地址
Content-MD5 Base64加密格式的內容MD5檢驗值

三. Web伺服器

3.1 虛擬主機

HTTP/1.1規範允許一臺HTTP伺服器搭建多個Web站點。利用虛擬主機的功能,可以在一臺伺服器上虛擬出多個主機,每個主機對映一個獨立域名。因此,當用戶訪問域名時,DNS域名系統會解析成IP地址,根據IP找到物理伺服器,然後再通過首部的HOST欄位找到相應的虛擬主機

3.2 代理伺服器

代理伺服器就是客戶端和服務端之間的“中間商”,就是HTTP請求通過代理伺服器轉發給伺服器,再將伺服器的響應返回給客戶端行為。代理伺服器用來作為快取伺服器,也可以用來隱藏使用者身份。

  • 正向代理:正向代理是從客戶端角度出發,為了從源伺服器取得內容,由客戶端向代理伺服器發出請求,並指定目標訪問伺服器,代理伺服器向源伺服器轉交需求,並將獲得的內容返回給客戶端。正向代理隱藏了真實請求的客戶端,即服務端並不知道正式請求的是誰。
  • 反向代理:反向代理是客戶端向反向代理代理伺服器發出請求,反向代理伺服器收到需求後判斷請求走向何處,然後再將響應返回給客戶端。反向代理隱藏了內部伺服器的資訊,使用者不需要知道具體哪一臺伺服器提供服務,只要知道反向代理伺服器是誰就好。反向代理通常被用作實現負載均衡。

四. HTTPS

4.1 什麼是HTTPS

超文字傳輸安全協議(英語:Hypertext Transfer Protocol Secure,縮寫:HTTPS,常稱為HTTP over TLS,HTTP over SSL或HTTP Secure)是一種通過計算機網路進行安全通訊的傳輸協議。HTTPS經由HTTP進行通訊,但利用SSL/TLS來加密資料包。HTTPS開發的主要目的,是提供對網站伺服器的身份認證,保護交換資料的隱私與完整性。

4.2 為什麼需要HTTPS

HTTP本身是明文傳輸,這就造成了很大的安全問題,為了解決安全問題,推出了HTTPS。HTTPS是在通訊介面用TLS(Transport Layer Security 傳輸層安全性協議),用於兩個應用程式間通過網路建立起安全的連線,防止在交換資料時收到竊聽以及篡改。

  • HTTP存在的問題:
    1. 通訊使用明文(不加密),內容可能被竊聽
    2. 無法證明報文的完整性,所以可能被篡改
    3. 不驗證通訊方的身份,因此有可能遭遇篡改
  • HTTPS協議相比HTTP的優勢
    1. 資料隱私:內容經過對稱加密,每個連線生成唯一的加密金鑰
    2. 資料完整性:內容傳輸經過完整性校驗
    3. 身份認證:第三方無法偽造服務端

4.3 HTTPS解決內容可能被竊聽--加密

HTTPS協議的主要功能都依賴於TLS/SSL協議,TLS/SSL協議的功能是心啊主要依賴於三類基本演算法:雜湊函式、對稱加密、非對稱加密,利用非對稱加密實現身份的認證和金鑰協商,而資料通訊則協商的對稱機密進行加密,然後基於雜湊函式驗證資訊的完整性。

  • 對稱加密:

    這種方式加密以及解密同用一個金鑰。加密和解密都需要用到金鑰,沒有金鑰就無法解密。反過來講,只要誰持有金鑰都能進行解密。

    以對稱加密的方式必須將金鑰傳送給對方,可是怎樣才能安全的傳送給對方呢?網際網路傳送很有可能被劫持,這就失去了加密的意義。

  • 非對稱加密:

    這種加密方式會有兩把金鑰,一把私有金鑰由服務端儲存起來,不讓任何人知道。而公開金鑰則可以隨意釋出,任何人都可以獲得。

    使用公開金鑰加密,傳送密文的一方使用對方公開的公鑰進行加密處理,對方收到由公鑰加密的資訊後,使用自己的私鑰進行解密。使用這種方式,即使資訊被劫持也無法得到裡面的資訊(就像一個上了鎖的保險箱)

    但非對稱加密中公鑰並不包含伺服器資訊,使用非對稱加密演算法無法確保伺服器身份的合法性,存在中間人攻擊的風險。同時非對稱加密過程也需要消耗一定的時間,降低資料傳輸效率

  • 混合加密(對稱加密+非對稱加密 HTTPS使用這種方式)

    對稱加密好處是解密效率快,非對稱加密是可以使得內容不被破解,兩者各有優缺點,將他們結合起來就會更大的發揮他們的優勢隱藏他們的缺點。

    具體為:傳送密文的一方使用服務端傳送過來的公鑰進行加密處理對稱金鑰,然後服務端用自己的私鑰解密拿到對稱金鑰,這樣可以確保交換的金鑰是安全的前提下,使用對稱加密的方式進行通訊

4.4 HTTPS解決身份偽裝問題--第三方認證

公鑰被調包,是因為客戶端無法分辨傳回來的到底是中間人還是伺服器。

在HTTPS中使用證書 + 數字簽名來解決這個問題

這裡假設加密方式是MD5,將網站資訊通過第三方機構的私鑰進行加密,生成數字簽名

假如中間人攔截後把伺服器的公鑰替換為自己的公鑰,因為數字簽名的存在,會導致客戶端簽名不匹配,這樣就防止了中間人替換公鑰的問題。

瀏覽器會內建一些權威第三方機構的公鑰。

4.5 總結:HTTPS的工作流程

  1. Client發起了一個HTTPS的請求,根據RFC2818的規定,Client知道需要連線Server的443(預設)埠。
  2. Server把事先配置好的公鑰證書(Public key certificate)返回給客戶端
  3. Client驗證公鑰證書:比如是否在有效期內,證書的用途是否匹配Client請求的站點,是不是在CRL吊銷列表中,它的上一級證書是否有效,這是一個遞迴過程,直到驗證到根證書(作業系統內建的Root證書或者Client內建的Root證書)。如果驗證通過則繼續,不通過則顯示警告資訊。
  4. Client使用偽隨機數生成加密使用的對稱金鑰,然後用證書加密這個對稱金鑰,發給Server
  5. Server使用自己的私鑰解密這個訊息,得到對稱金鑰。至此Client與Server雙方都持有相同的對稱金鑰。
  6. Server使用對稱金鑰加密“內容”,傳送給Client
  7. Client使用對稱金鑰解密相應的密文,得到“內容”

4.6 HTTP與HTTPS的區別

  1. HTTPS比HTTP更加安全,對搜尋引擎更友好,利於SEO,谷歌、百度優先搜尋HTTPS的網頁

  2. HTTP協議執行在TCP之上,所有傳輸的內容都是明文,HTTPS執行在SSL/TLS之上,SSL/TLS執行在TCP之上,所有傳輸的內容都經過加密的。

  3. HTTP和HTTPS使用的是完全不同的連線方式,用的埠也不一樣,前者是80,後者是443。

  4. http的連線很簡單,是無狀態的;HTTPS協議是由HTTP+SSL協議構建的可進行加密傳輸、身份認證的網路協議,可以有效的防止運營商劫持,解決了防劫持的一個大問題,比http協議安全

五. Web安全

5.1 XSS攻擊

5.1.1什麼是XSS

Cross-Site Scripting(跨站指令碼攻擊)簡稱XSS,是一種程式碼注入攻擊。攻擊者通過在目標網站上注入惡意指令碼,使之在使用者瀏覽器上執行。利用這些惡意指令碼,攻擊者可以獲得使用者的敏感資訊如Cookie、SessionID等,進而危害資料安全。

XSS的本質是:惡意程式碼未經過過濾,與網站正常的程式碼混在一起,瀏覽器無法分辨哪些指令碼是可信的。導致惡意指令碼被執行。

一些使用者的UGC內容都可以進行注入,所以以下內容均不可信:

  • 來自使用者的UGC內容
  • 來自第三方的連結
  • URL引數
  • POST引數
  • Referer(可能來自不可信的來源)
  • Cookie(可能來自子域注入)

5.1.2 XSS攻擊詳述

根據攻擊來源,可以將XSS攻擊分為儲存型、反射型、DOM型

儲存型XSS

儲存型XSS攻擊步驟:

  1. 攻擊者將惡意程式碼提交到目標網站的資料庫中。

  2. 使用者開啟目標網站時,網站服務端將惡意程式碼從資料庫取出,拼接在HTML中返回給瀏覽器

  3. 使用者瀏覽器收到響應後解析執行,混在其中的惡意程式碼也被執行

  4. 惡意程式碼竊取使用者資料併發送到攻擊者的網站,或者冒充使用者行為,呼叫目標網站介面執行攻擊者指定的操作

常用於帶有使用者儲存資料的網站功能,如論壇發帖、商品評論、使用者私信

反射型XSS

反射型XSS的攻擊步驟:

  1. 攻擊者構造出特殊的URL,其中包含惡意程式碼。
  2. 使用者開啟惡意程式碼的URL,網站伺服器從URL中取出,拼接在HTML返回給瀏覽器
  3. 使用者瀏覽器接收到惡意程式碼後解析執行,混在其中的惡意程式碼也被執行
  4. 惡意程式碼竊取使用者資料併發送到攻擊者的網站,或者冒充使用者行為,呼叫目標網站介面執行攻擊者指定的操作

由於需要使用者主動開啟惡意的URL才能生效,攻擊者往往結合多種手段誘導使用者點選

DOM型XSS

DOM型XSS攻擊的步驟:

  1. 攻擊者構造出特殊的 URL,其中包含惡意程式碼。
  2. 使用者開啟帶有惡意程式碼的 URL。
  3. 使用者瀏覽器接收到響應後解析執行,前端 JavaScript 取出 URL 中的惡意程式碼並執行。
  4. 惡意程式碼竊取使用者資料併發送到攻擊者的網站,或者冒充使用者的行為,呼叫目標網站介面執行攻擊者指定的操作。

DOM型XSS與前兩種XSS的區別:DOM型取出和執行惡意程式碼由瀏覽器端執行,屬於前端的安全漏洞,而其他兩種都屬於服務端的安全漏洞。

5.1.3 XSS攻擊的預防

預防儲存型和反射型的XSS攻擊
  1. 改為純前端渲染,將程式碼和資料分隔開

    在純前端渲染中我們會明確告訴瀏覽器:下面要設定的內容是文字(innnerTetx),還是屬性(.setAttribute),還是樣式(.style。

  2. 對HTML做充分的轉義

    需要採用合適的轉義庫,因為HTML的編碼是十分的複雜,需要在不同的上下文要使用相應的轉義規則

預防DOM型XSS攻擊

DOM型XSS攻擊,實際上是網站前端JavaScript程式碼本身不夠嚴謹,把不可信的資料作為程式碼執行。

在使用 .innerHTML.outerHTMLdocument.write() 時要特別小心,不要把不可信的資料作為 HTML 插到頁面上,而應儘量使用 .textContent.setAttribute() 等。

避免字串中拼接不可信的資料

5.2 CSRF攻擊

5.2.1 什麼是CSRF

CSRF(Cross-site request forgery)跨站請求偽造:攻擊者誘導受害者進入第三方網站,在第三方網站中,向被攻擊的網站傳送跨站請求。利用受害者在被攻擊網站已獲取的註冊憑證,繞過後臺的使用者驗證,達到冒充使用者被攻擊的網站進行某項操作的目的。

5.2.2 CSRF攻擊的流程

  1. 受害者登陸站點A,並保留了登陸憑證
  2. 攻擊者誘導受害者訪問了站點B
  3. 站點B向站點A傳送了請求,瀏覽器會預設攜帶站點A的Cookie的資訊
  4. 站點A收到請求,驗證出是受害者的憑證,便迴應了站點B的請求
  5. 攻擊完成,站點B在受害者不知情的情況下,冒充受害者完成了攻擊

5.2.3 CSRF的預防

同源檢測

在HTTP協議中,每一個非同步請求都會攜帶兩個Header ,用來標記來源域名,分別是Origin Header Referer Header。這兩個Header在請求時,大多數是會自動帶上,並且不能由前端自定義內容,伺服器可以解析這兩個Header中的域名,確定請求的來源域。

  • Origin Header

    在部分與CSRF有關的請求中,請求的Header中會攜帶Origin欄位,欄位內包含請求的域名。但部分情況Origin並不存在:

    • IE11同源策略:

      由於IE11的同源策略不同,不會在跨站的CORS請求上新增Origin標頭,Referer頭將是唯一標識。

    • 302重定向:

      在302重定向後,Origin不包含在重定向的請求中,因為302是臨時重定向,瀏覽器不會將Origin洩漏給新伺服器。

  • Referer Header

    根據HTTP協議,在HTTP頭中有一個欄位叫做Referer,記錄了該HTTP請求的來源地址。但由於每個瀏覽器的對Referer的具體實現不同,並且攻擊者是可以隱藏甚至修改自己請求的Referer。

CSRF Token

但使用者開啟頁面的時候,伺服器會給這個使用者生成一個Token,該Token通過加密演算法對資料進行加密,一般Token都包括字串和時間戳的組合。由於CSRF攻擊就是冒用使用者的Cokkie,所以我們不能再將Token放在Cookie中,為了安全起見我們可以把Token放在伺服器Session中,之後每次頁面載入時,遍歷DOM樹將其中所有aform加入Token。但對於動態生成的HTML,這種方法就沒用。

增加驗證碼和密碼

驗證碼可以很好的防禦住CSRF攻擊,但我們不能多次新增驗證碼和密碼,這樣對使用者的體驗是很不好的。但是我們在轉賬、交易等操作,新增密碼輸入、驗證碼可以確保我們賬戶安全。

雙重Cookie

利用CSRF攻擊不能獲取到使用者的Cookie的特點,我們可以要求Ajax和表單請求攜帶一個Cookie中的值。

  1. 在使用者訪問網站頁面時,向請求域注入一個Cookie,內容為隨機字元
  2. 在前端向後端傳送請求時,取出Cookie,並新增到URL的引數中。
  3. 後端介面驗證Cookie中的欄位和URL引數中的欄位是否一樣

為了從源頭解決CSRF問題,Google起草了一份草案來改進HTTP協議,那就是為Set-Cookie響應頭新增Samesite屬性,用來標明是否為同站Cookie。

  • Samesite=Strict

    嚴格模式,表明這個Cookie在任何情況下都不可能作為第三方Cookie,絕無例外。比如說我們從百度搜索的頁面的連結進入淘寶後,在嚴格模式下都不會是登入狀態,因為淘寶不會接受這個Cookie。

  • Samesite=Lax

    寬鬆模式,這個模式下不同網站通過連結跳轉是不受影響的,會發送Cookie,但假如是非同步操作或者是頁面跳轉是通過表單的POST提交觸發的則也不會發送Cookie。

但目前來說SamesiteCookie相容性並不好,Safari並不支援。並且SamesiteCookie並不支援子域。例如:在topic.a.com下的Cookie並不支援使用a.com下設定的samesiteCookie。

搬運文章

解密HTTP/2與HTTP/3 的新特性

HTTP1.0、HTTP1.1 和 HTTP2.0 的區別

HTTP協議詳解(一)

前端基礎篇之HTTP協議

你所知道的3xx狀態碼

如何理解HTTP響應的狀態碼?

HTTP協議頭部與Keep-Alive模式詳解

分分鐘讓你理解HTTPS

深入理解HTTPS的工作原理

看圖學HTTPS

前端安全系列(一)

前端安全系列(二)

【面試篇】寒冬求職之你必須要懂的Web安全