HTTP/2 防止了哪些漏洞?
进一步来说:
- 它是否可以防止 HTTP 请求走私?
- 它是否可以防止 HTTP 响应拆分/CRLF 注入?
HTTP/2 防止了哪些漏洞?
进一步来说:
FAQ中提到的具体安全改进与 TLS 加密有关:HTTP/2 必须至少使用 TLS 1.2 并且它支持SNI。此外,HTTP/2 引入了一个TLS 1.2 密码套件黑名单,实现可能将其视为连接错误。
HTTP/2 定义了所需的 TLS 配置文件;这包括版本、密码套件黑名单和使用的扩展。
有关详细信息,请参阅规范。
还讨论了其他机制,例如对 HTTP:// URL 使用 TLS(所谓的“机会加密”);参见RFC 8164。
除此之外,HTTP/2 提供了安全压缩功能,使您能够在禁用 TLS 1.2 压缩的同时进行标头压缩。从http2解释:
HTTPS 和 SPDY 压缩被发现容易受到BREACH 和CRIME攻击。通过将已知文本插入到流中并弄清楚它如何改变输出,攻击者可以找出加密有效负载中发送的内容。
对协议的动态内容进行压缩 - 不会容易受到这些攻击之一 - 需要一些思考和仔细考虑。这就是 HTTPbis 团队试图做的事情。
输入HPACK,HTTP/2 的标头压缩,顾名思义,它是一种专为 http2 标头设计的压缩格式,它在单独的 Internet 草案中指定。新格式与其他对策(例如要求中介不要压缩特定标头和可选的帧填充的位)一起,应该会使利用压缩变得更加困难。
HTTP 请求走私并不是 HTTP/1.1 协议本身的真正漏洞,但是指定请求如何结束的两种不同方式 ( Content-Length
& Transfer-Encoding
) 的存在为糟糕的 HTTP 代理服务器链实现留下了空间。在 HTTP/2 中只有一个:
简而言之,HTTP/2 将 HTTP 协议通信分解为二进制编码帧的交换,然后将其映射到属于特定流的消息,所有这些都在单个 TCP 连接中多路复用。
对于这些二进制帧,帧有效载荷的结尾(例如包含请求)由帧头(RFC 7540, 4.1Length (24)
)中的字段指定,这使得它明确。因此,HTTP 请求走私文章甚至提到使用 HTTP/2 进行后端连接作为防止这些漏洞的一种方法:
防止出现 HTTP 请求走私漏洞的一些通用方法如下:
- 禁用后端连接的重用,以便通过单独的网络连接发送每个后端请求。
- 使用 HTTP/2 进行后端连接,因为该协议可以防止请求之间的边界不明确。
- 对前端和后端服务器使用完全相同的 Web 服务器软件,以便它们就请求之间的边界达成一致。
HTTP 响应拆分只是CRLF 注入的一个示例。处理标头块的方式(RFC 7540 4,尤其是4.3)仅使用两个 CRLF 就可以减少从标头块中逃逸的空间:
每个标头块都作为一个离散单元处理。标头块必须作为连续的帧序列传输,没有任何其他类型的交错帧或来自任何其他流的帧。HEADERS 或 CONTINUATION 帧序列中的最后一帧设置了 END_HEADERS 标志。PUSH_PROMISE 或 CONTINUATION 帧序列中的最后一帧设置了 END_HEADERS 标志。这允许标题块在逻辑上等同于单个帧。
正如 Google 的HTTP/2 简介中所解释的,换行符通常也不那么重要:
与换行符分隔的明文 HTTP/1.x 协议不同,所有 HTTP/2 通信都被拆分为更小的消息和帧,每个都以二进制格式编码。
虽然标头列表的序列化还可以帮助解决其他类型的 CRLF 漏洞,例如HTTP Header Injection,但它并不能自动阻止 Web 应用程序中所有可能的 CRLF 漏洞,因为 Web 应用程序仍然可以处理%0d%0a
GET 数据、POST 数据、cookies 或任何单个标题中。为了防止这种情况,例如Netsparker 安全团队建议:
如何防止 Web 应用程序中的 CRLF/HTTP 标头注入
最好的预防技术是不要直接在响应头中使用用户输入。如果这不可能,您应该始终使用函数来编码 CRLF 特殊字符。另一个良好的 Web 应用程序安全最佳实践是将您的编程语言更新为不允许将 CR 和 LF 注入设置 HTTP 标头的函数中的版本。