http://www.blogjava.net/yongboy/archive/2015/03/24/423791.html
零。前言
這里整理了一下錯誤和安全相關(guān)部分簡單記錄。
一。HTTP/2錯誤
1. 錯誤定義
HTTP/2定義了兩種類型錯誤:
- 導(dǎo)致整個連接不可使用的錯誤為連接錯誤(connection error)
- 單獨出現(xiàn)在單個連接上的錯誤為流錯誤(stream error)
2. 錯誤代碼
錯誤代碼,32位正整數(shù)表示錯誤原因,RST_STREAM和GOAWAY幀中包含。
未知或不支持的錯誤代碼可以選擇忽略,或作為INTERNAL_ERROR錯誤對待都可以。
3. 連接錯誤處理
一般來講連接錯誤很嚴重,會導(dǎo)致處理進程無法進行下去,或影響到整個連接的狀態(tài)。
- 終端一旦遇上連接錯誤,需第一時間在最后一個可用流上發(fā)送包含錯誤原因GOAWAY幀過去,然后關(guān)閉連接
- GOAWAY有可能不被對端成功接收到,若成功接收可獲得連接被終止的原因
- 終端可在任何時間終止連接,也可以把流錯誤作為連接錯誤對待。但都應(yīng)該在關(guān)閉連接之前發(fā)送一個GOAWAY幀告知對方
4. 流錯誤
一般來講具體流上的流錯誤不會影響到其它流的處理。
- 終端檢測到流錯誤,需要發(fā)送一個RST_STREAM幀,其包含了操作到錯誤流標識符
- RST_STREAM應(yīng)當(dāng)是發(fā)送錯誤流最后一個幀,內(nèi)含錯誤原因。
- 發(fā)送方在發(fā)送之后,需要準備接收對端將要或即將發(fā)送過來的幀數(shù)據(jù),處理方式就是忽略之,除非是可以修改連接狀態(tài)幀
- 一般來講,終端不應(yīng)該發(fā)送多個RST_STREAM幀,但若在一個往返時間之后已關(guān)閉的流上能夠繼續(xù)接收幀,則需要發(fā)送再次發(fā)送一個RST_STREAM幀,處理這種行為不端的實現(xiàn)。
- 終端在接收到RST_STREAM幀之后,不能響應(yīng)一個RST_STREAM幀,避免死循環(huán)
5. 連接終止
TCP連接被關(guān)閉或重置時仍有處于"open"或"half closed"的流將不能自動重試。
二。HTTP/2安全注意事項
1. 跨協(xié)議攻擊
跨協(xié)議攻擊,字面上理解就很簡單,比如攻擊者構(gòu)建HTTP/1.1請求直接轉(zhuǎn)發(fā)給僅僅支持HTTP/2的服務(wù)器,以期待獲取攻擊效果。
這里有一篇講解跨協(xié)議攻擊的文章:http://www.freebuf.com/articles/web/19622.html
TLS的加密機制使得攻擊者很難獲得明文,另外TLS的ALPN協(xié)議擴展可以很輕松處理請求是否需要作為HTTP/2請求進行處理,總之可有效阻止對基于TLS的其它協(xié)議攻擊。
基于標準版TCP沒有TLS和ALPN的幫忙,客戶端所發(fā)送連接序言前綴為PRI字符串用來混淆HTTP/1.1服務(wù)器,但對其它協(xié)議沒有提供保護,僅限于此。但在處理時,若接收到HTTP/1.1的請求,沒有包含Upgrade升級字段,則需要認為是一個跨協(xié)議攻擊。
總之,程序要盡可能的健壯,容錯,針對非法的請求,直接關(guān)閉對方連接。
2. 中介端數(shù)據(jù)轉(zhuǎn)換封裝的攻擊
中介所做的HTTP/1.1和HTTP/2之間轉(zhuǎn)換,會存在攻擊點:
- HTTP/2頭字段名稱編碼允許使用HTTP/1.1沒有使用到的頭字段名稱,中介在轉(zhuǎn)換HTTP/2到HTTP/1.1時就容易出現(xiàn)包含非法請求頭字段HTTP/1.1數(shù)據(jù)。
- HTTP/2允許頭字段值可以是非法值,諸如回車(CR, ASCII 0xd), 換行 (LF, ASCII 0xa), 零字符 (NUL, ASCII 0x0),這在逐字解析實現(xiàn)時是一個風(fēng)險。
解決方式,一旦發(fā)現(xiàn)非法頭字段名稱,以及非法頭字段值,都作為不完整、殘缺數(shù)據(jù)對待,或丟棄,或忽略。
3. 推送內(nèi)容的緩存
推送內(nèi)容有保證的服務(wù)器提供,是否緩存由頭字段Cache-Control控制。
但若服務(wù)器上多租戶形式(SAAS),每一個租戶使用一小部分URL空間,比如 tenant1.domain.com,tenant2.domain.com,服務(wù)器需要確保沒有授權(quán)的租戶不能夠推送超于預(yù)期的資源,覆蓋已有內(nèi)容。
原始服務(wù)器沒有被授權(quán)使用推送,既不能夠違規(guī)發(fā)送推送,也不能夠被緩存。
4. 拒絕服務(wù)攻擊注意事項
- HTTP/2因為要為流、報頭壓縮、流量控制等特性占用資源較多,因此針對每一個連接的內(nèi)存分配要設(shè)置限額,否則很少的連接占滿內(nèi)存,無法正常服務(wù)
- 針對單個連接,規(guī)范對PUSH_PROMISE幀數(shù)量沒有約束,但客戶端需要設(shè)置一個上限值,這也是確定需要維護的"reserved (remote)"狀態(tài)的數(shù)量,超出限額需要報ENHANCE_YOUR_CALM類型流錯誤
- SETTINGS幀有可能會被濫用導(dǎo)致對端需要花費時間解析處理設(shè)置限制等,濫用情況包括包含未定義的參數(shù),以及同一個參數(shù)多次出現(xiàn)等,類似于WINDOW_UPDATE和PRIORITY幀都會存在濫用的情況;這些幀被濫用導(dǎo)致資源耗費情況嚴重
- 大量小幀或空幀一樣會被濫用,但又符合邏輯,耗費服務(wù)器資源在處理報文頭部上面。比如空負載DATA幀,以及用于攜帶報文頭部數(shù)據(jù)的CONTINUATION幀,都屬于安全隱患
- 報頭壓縮存在潛在風(fēng)險,也會被濫用,詳情可參考HPACK協(xié)議第七章:http://http2.github.io/http2-spec/compression.html#Security
- 終端中途發(fā)送的SETTINGS幀所定義參數(shù)不是立即可以生效的,這會導(dǎo)致對端在實際操作時可能會超過最新的限制。建議直接在連接建立時在連接序言內(nèi)包含設(shè)置值,就算如此,客戶端也會存在超出服務(wù)器端連接序言中所設(shè)置的最新限定值。
總之,諸如SETTINGS幀、小幀或空幀,報頭壓縮被合理濫用時,表明上看符合邏輯,會造成資源過度消耗。這需要服務(wù)器端監(jiān)控跟蹤到此種行為,并且設(shè)置使用數(shù)量的上限,一旦發(fā)現(xiàn)直接報ENHANCE_YOUR_CALM類型連接錯誤。
5. 報頭塊大小限制
報頭塊過大導(dǎo)致實現(xiàn)需要維護大量的狀態(tài)開銷。另外,根據(jù)報頭字段進行路由的情況,若此報頭字段出現(xiàn)在一系列報頭塊幀的最后一個幀里面,可能會導(dǎo)致無法正常路由到目的地。若被緩存會導(dǎo)致耗費大量的內(nèi)存。這需要設(shè)置SETTINGS_MAX_HEADER_LIST_SIZE參數(shù)限制報頭最大值,以盡可能的避免出現(xiàn)以上情況。
服務(wù)器一旦接收到超過報頭限制請求,需要響應(yīng)一個431(請求頭過大) HTTP狀態(tài)碼,客戶端呢可直接丟掉響應(yīng)。
6. 壓縮使用的安全隱患
7. 填充使用的安全隱患
一般來講,填充可用來混淆幀的真實負載長度,稍加保護,降低攻擊的可能性。但若不當(dāng)?shù)奶畛洳呗裕汗潭ㄌ畛鋽?shù)、可輕松推導(dǎo)出填充規(guī)則等情況都會降低保護的力度,都有可能會被攻擊者破解。
中介設(shè)備應(yīng)該保留DATA幀的填充(需要避免如上所述一些情況),但可丟棄HEADERS和PUSH_PROMISE幀的填充。
三。TLS
HTTP/2加密建立在TLS基礎(chǔ),關(guān)于TLS,維基百科上有解釋:http://zh.wikipedia.org/wiki/%E5%82%B3%E8%BC%B8%E5%B1%A4%E5%AE%89%E5%85%A8%E5%8D%94%E8%AD%B0
摘取一張圖,可說明基于ALPN協(xié)議擴展定義的協(xié)商流程:
其它要求:
- 只能基于TLS >= 1.2版本。目前TLS 1.3為草案版本,正式版本目前尚未可知。目前只有TLS 1.2可選。
- 必須支持Server Name Indication (SNI) [TLS-EXT]擴展,客戶端在連接協(xié)商階段需要攜帶上域名
- 基于TLS 1.3或更高版本構(gòu)建,僅需要支持SNI擴展。TLS 1.2要求較多
- 基于TLS 1.2構(gòu)建
- 必須禁用壓縮機制。不恰當(dāng)壓縮機制會導(dǎo)致信息外露,HTTP/2報頭有壓縮機制
- 必須禁用重新協(xié)商機制。終端對待TLS 1.2重新協(xié)商作為PROTOCOL_ERROR類型連接錯誤對待;密碼套件加密次數(shù)限制導(dǎo)致連接一直掛起等待不可用
- 終端可以通過重新協(xié)商提供對客戶端憑證保護功能在握手期間,重新協(xié)商必須發(fā)生在發(fā)送連接序言之前進行。服務(wù)器當(dāng)看到重新協(xié)商請求時應(yīng)該請求客戶端證書在連接建立后
- 當(dāng)客戶端請求受保護的特定資源時,服務(wù)器可以響應(yīng)HTTP_1_1_REQUIRED錯誤,可有效阻止重新協(xié)商機制
四。小結(jié)
這里簡單記錄HTTP/2錯誤和安全相關(guān)事項,本系列規(guī)范學(xué)習(xí)到此告一段落。