聶永的博客

          記錄工作/學習的點點滴滴。

          HTTP/2筆記之錯誤處理和安全

          零。前言

          這里整理了一下錯誤和安全相關部分簡單記錄。

          一。HTTP/2錯誤

          1. 錯誤定義

          HTTP/2定義了兩種類型錯誤:

          • 導致整個連接不可使用的錯誤為連接錯誤(connection error)
          • 單獨出現在單個連接上的錯誤為流錯誤(stream error)

          2. 錯誤代碼

          錯誤代碼,32位正整數表示錯誤原因,RST_STREAM和GOAWAY幀中包含。

          未知或不支持的錯誤代碼可以選擇忽略,或作為INTERNAL_ERROR錯誤對待都可以。

          3. 連接錯誤處理

          一般來講連接錯誤很嚴重,會導致處理進程無法進行下去,或影響到整個連接的狀態。

          • 終端一旦遇上連接錯誤,需第一時間在最后一個可用流上發送包含錯誤原因GOAWAY幀過去,然后關閉連接
          • GOAWAY有可能不被對端成功接收到,若成功接收可獲得連接被終止的原因
          • 終端可在任何時間終止連接,也可以把流錯誤作為連接錯誤對待。但都應該在關閉連接之前發送一個GOAWAY幀告知對方

          4. 流錯誤

          一般來講具體流上的流錯誤不會影響到其它流的處理。

          • 終端檢測到流錯誤,需要發送一個RST_STREAM幀,其包含了操作到錯誤流標識符
          • RST_STREAM應當是發送錯誤流最后一個幀,內含錯誤原因。
          • 發送方在發送之后,需要準備接收對端將要或即將發送過來的幀數據,處理方式就是忽略之,除非是可以修改連接狀態幀
          • 一般來講,終端不應該發送多個RST_STREAM幀,但若在一個往返時間之后已關閉的流上能夠繼續接收幀,則需要發送再次發送一個RST_STREAM幀,處理這種行為不端的實現。
          • 終端在接收到RST_STREAM幀之后,不能響應一個RST_STREAM幀,避免死循環

          5. 連接終止

          TCP連接被關閉或重置時仍有處于"open"或"half closed"的流將不能自動重試。

          二。HTTP/2安全注意事項

          1. 跨協議攻擊

          跨協議攻擊,字面上理解就很簡單,比如攻擊者構建HTTP/1.1請求直接轉發給僅僅支持HTTP/2的服務器,以期待獲取攻擊效果。

          這里有一篇講解跨協議攻擊的文章:http://www.freebuf.com/articles/web/19622.html

          TLS的加密機制使得攻擊者很難獲得明文,另外TLS的ALPN協議擴展可以很輕松處理請求是否需要作為HTTP/2請求進行處理,總之可有效阻止對基于TLS的其它協議攻擊。

          基于標準版TCP沒有TLS和ALPN的幫忙,客戶端所發送連接序言前綴為PRI字符串用來混淆HTTP/1.1服務器,但對其它協議沒有提供保護,僅限于此。但在處理時,若接收到HTTP/1.1的請求,沒有包含Upgrade升級字段,則需要認為是一個跨協議攻擊。

          總之,程序要盡可能的健壯,容錯,針對非法的請求,直接關閉對方連接。

          2. 中介端數據轉換封裝的攻擊

          中介所做的HTTP/1.1和HTTP/2之間轉換,會存在攻擊點:

          1. HTTP/2頭字段名稱編碼允許使用HTTP/1.1沒有使用到的頭字段名稱,中介在轉換HTTP/2到HTTP/1.1時就容易出現包含非法請求頭字段HTTP/1.1數據。
          2. HTTP/2允許頭字段值可以是非法值,諸如回車(CR, ASCII 0xd), 換行 (LF, ASCII 0xa), 零字符 (NUL, ASCII 0x0),這在逐字解析實現時是一個風險。

          解決方式,一旦發現非法頭字段名稱,以及非法頭字段值,都作為不完整、殘缺數據對待,或丟棄,或忽略。

          3. 推送內容的緩存

          推送內容有保證的服務器提供,是否緩存由頭字段Cache-Control控制。

          但若服務器上多租戶形式(SAAS),每一個租戶使用一小部分URL空間,比如 tenant1.domain.com,tenant2.domain.com,服務器需要確保沒有授權的租戶不能夠推送超于預期的資源,覆蓋已有內容。

          原始服務器沒有被授權使用推送,既不能夠違規發送推送,也不能夠被緩存。

          4. 拒絕服務攻擊注意事項

          • HTTP/2因為要為流、報頭壓縮、流量控制等特性占用資源較多,因此針對每一個連接的內存分配要設置限額,否則很少的連接占滿內存,無法正常服務
          • 針對單個連接,規范對PUSH_PROMISE幀數量沒有約束,但客戶端需要設置一個上限值,這也是確定需要維護的"reserved (remote)"狀態的數量,超出限額需要報ENHANCE_YOUR_CALM類型流錯誤
          • SETTINGS幀有可能會被濫用導致對端需要花費時間解析處理設置限制等,濫用情況包括包含未定義的參數,以及同一個參數多次出現等,類似于WINDOW_UPDATE和PRIORITY幀都會存在濫用的情況;這些幀被濫用導致資源耗費情況嚴重
          • 大量小幀或空幀一樣會被濫用,但又符合邏輯,耗費服務器資源在處理報文頭部上面。比如空負載DATA幀,以及用于攜帶報文頭部數據的CONTINUATION幀,都屬于安全隱患
          • 報頭壓縮存在潛在風險,也會被濫用,詳情可參考HPACK協議第七章:http://http2.github.io/http2-spec/compression.html#Security
          • 終端中途發送的SETTINGS幀所定義參數不是立即可以生效的,這會導致對端在實際操作時可能會超過最新的限制。建議直接在連接建立時在連接序言內包含設置值,就算如此,客戶端也會存在超出服務器端連接序言中所設置的最新限定值。

          總之,諸如SETTINGS幀、小幀或空幀,報頭壓縮被合理濫用時,表明上看符合邏輯,會造成資源過度消耗。這需要服務器端監控跟蹤到此種行為,并且設置使用數量的上限,一旦發現直接報ENHANCE_YOUR_CALM類型連接錯誤。

          5. 報頭塊大小限制

          報頭塊過大導致實現需要維護大量的狀態開銷。另外,根據報頭字段進行路由的情況,若此報頭字段出現在一系列報頭塊幀的最后一個幀里面,可能會導致無法正常路由到目的地。若被緩存會導致耗費大量的內存。這需要設置SETTINGS_MAX_HEADER_LIST_SIZE參數限制報頭最大值,以盡可能的避免出現以上情況。

          服務器一旦接收到超過報頭限制請求,需要響應一個431(請求頭過大) HTTP狀態碼,客戶端呢可直接丟掉響應。

          6. 壓縮使用的安全隱患

          • 針對安全通道,不能使用同一個壓縮字典壓縮保密的關鍵數據和易受攻擊者控制的數據
          • 來源數據不能確定為完全可靠,就不應該使用壓縮機制
          • 通用流的壓縮不能在基于TLS的HTTP/2上使用這一部分,可參考 http://http2.github.io/http2-spec/compression.html#Security

          7. 填充使用的安全隱患

          一般來講,填充可用來混淆幀的真實負載長度,稍加保護,降低攻擊的可能性。但若不當的填充策略:固定填充數、可輕松推導出填充規則等情況都會降低保護的力度,都有可能會被攻擊者破解。

          中介設備應該保留DATA幀的填充(需要避免如上所述一些情況),但可丟棄HEADERS和PUSH_PROMISE幀的填充。

          三。TLS

          HTTP/2加密建立在TLS基礎,關于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協議擴展定義的協商流程:

          其它要求:

          • 只能基于TLS >= 1.2版本。目前TLS 1.3為草案版本,正式版本目前尚未可知。目前只有TLS 1.2可選。
          • 必須支持Server Name Indication (SNI) [TLS-EXT]擴展,客戶端在連接協商階段需要攜帶上域名
          • 基于TLS 1.3或更高版本構建,僅需要支持SNI擴展。TLS 1.2要求較多
          • 基于TLS 1.2構建
            • 必須禁用壓縮機制。不恰當壓縮機制會導致信息外露,HTTP/2報頭有壓縮機制
            • 必須禁用重新協商機制。終端對待TLS 1.2重新協商作為PROTOCOL_ERROR類型連接錯誤對待;密碼套件加密次數限制導致連接一直掛起等待不可用
            • 終端可以通過重新協商提供對客戶端憑證保護功能在握手期間,重新協商必須發生在發送連接序言之前進行。服務器當看到重新協商請求時應該請求客戶端證書在連接建立后
            • 當客戶端請求受保護的特定資源時,服務器可以響應HTTP_1_1_REQUIRED錯誤,可有效阻止重新協商機制

          四。小結

          這里簡單記錄HTTP/2錯誤和安全相關事項,本系列規范學習到此告一段落。

          posted on 2015-03-24 15:27 nieyong 閱讀(7217) 評論(0)  編輯  收藏 所屬分類: HTTP

          公告

          所有文章皆為原創,若轉載請標明出處,謝謝~

          新浪微博,歡迎關注:

          導航

          <2015年3月>
          22232425262728
          1234567
          891011121314
          15161718192021
          22232425262728
          2930311234

          統計

          常用鏈接

          留言簿(58)

          隨筆分類(130)

          隨筆檔案(151)

          個人收藏

          最新隨筆

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 平塘县| 连州市| 尖扎县| 鹤岗市| 陈巴尔虎旗| 慈利县| 江源县| 老河口市| 郎溪县| 巴塘县| 探索| 如皋市| 江安县| 甘肃省| 太谷县| 海安县| 桦甸市| 上犹县| 佳木斯市| 莒南县| 连云港市| 司法| 成都市| 竹山县| 铜山县| 山西省| 合作市| 邛崃市| 辽阳市| 康定县| 晋中市| 黄平县| 九台市| 都匀市| 北辰区| 普兰店市| 宜州市| 庆城县| 临猗县| 井冈山市| 鹤峰县|