审查者忽略未加密的 HTTP/2 流量

使用未加密的 HTTP/2 绕过审查

作者

隶属关系

Felix Lange* Paderborn University Niklas Niere* Paderborn University Jonathan von Niessen* Paderborn University

发布时间

2024年11月19日

内容

摘要 介绍与背景

结果

讨论

结论 *作者按字母顺序排列 – 所有人都做出了同等贡献

摘要

全球的审查者长期以来一直在审查未加密的 HTTP 流量。 在这篇博文中,我们表明,一个特定的 HTTP 版本——未加密的 HTTP/2——不受中国和伊朗审查的影响。 我们通过未加密的 HTTP/2 访问这两个国家/地区原本被审查的网站。 尽管没有 Web 浏览器实现未加密的 HTTP/2,但我们检测到高达 6.28% 的网站支持未加密的 HTTP/2 流量。 为了帮助社区并促进未来的研究,我们提供了一个工具来评估网站对未加密 HTTP 的支持。 最后,我们讨论了未加密的 HTTP/2 用于规避审查的局限性和潜力。 我们认为我们的发现是对当前规避审查技术的有趣补充。 注意:不要通过未加密的 HTTP/2 发送敏感数据,它可能会被窃听!

介绍与背景

在本节中,我们将提供有关 HTTP 及其审查的背景信息。 我们特别强调 HTTP/2 及其与先前 HTTP 版本的比较。

HTTP (审查)

HTTP 可以被认为是访问 Internet 上网站的_协议_。 虽然 HTTP 通常与 TLS 结合使用,但对纯 HTTP 协议的审查仍然存在,并且之前的研究广泛分析了最常见的 HTTP/1.1 版本。 这些工作发现,中国和伊朗等地的审查者会使用 Host 标头和请求路径中的信息来确定是否应审查 HTTP 请求。 下面的 HTTP/1.1 GET 请求表明审查者可以轻松提取请求的路径和域名:

GET /<request path> HTTP/1.1
Host: <censored_domain>

为了审查请求,审查者会注入 TCP RST 数据包、HTTP 阻止页面或对整个连接进行空路由。

HTTP/2

如上所述,对 HTTP/1.1 的审查已被广泛分析。 然而,对于较新版本 HTTP/2 的研究却很少。 HTTP/2 保持了与其前身相同的语义:它使用相同的端口号,通过 TCP 运行,最重要的是,它以未加密的方式传递请求路径和访问的域名,如下面的示例 HTTP/2 请求所示。

:method       GET
:scheme       HTTP
:host        <censored_domain>
:path        <request_path>

尽管 HTTP/2 与 HTTP/1.1 相似,但 HTTP/2 通过从基于文本的格式切换到二进制格式引入了一个重大变化。 虽然由于缺少加密,HTTP/2 仍然很容易被审查,但 HTTP/2 的二进制格式使得审查者的工作变得复杂,因为它需要不同的解析机制。 为了促进从 HTTP/1.1 升级到 HTTP/2,客户端可以使用两种机制之一:使用 HTTP/2 连接(预先知道)或升级现有的 HTTP/1.1 连接(升级机制)。 下面,我们描述这两种机制。

预先知道

使用预先知道,客户端直接尝试与服务器通信 HTTP/2。 作为初始步骤,客户端与服务器建立 TCP 连接。 然后,客户端发送所谓的连接序言,后跟一个 SETTINGS 帧。 专门定义此连接序言是为了在不支持 HTTP/2 的 HTTP 服务器上触发错误。 SETTINGS 帧包含连接的其他配置参数。 发送连接序言和 SETTINGS 帧后,客户端发送其 HTTP/2 请求。 如果服务器支持 HTTP/2,它会响应自己的连接序言,其中包含一个 SETTINGS 帧,并使用 HTTP/2 响应来回答客户端的 HTTP/2 请求。

升级机制

在升级机制期间,客户端与服务器建立 TCP 连接,然后发送 HTTP/1.1 请求,其中包括 Upgrade 和 HTTP2-Settings 标头。 HTTP/1.1 升级请求的示例可能如下所示:

GET / HTTP/1.1
Host: server.example.com
Connection: Upgrade, HTTP2-Settings
Upgrade: h2c
HTTP2-Settings: <HTTP/2 SETTINGS payload 的 base64url 编码>

如果服务器支持升级机制,它将响应 101 状态代码,指示切换协议,然后转换为 HTTP/2 连接。 成功的服务器答案示例可能如下所示:

HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: h2c
[ HTTP/2 answer for "GET /" ... ]

最初由 RFC 7540 定义,但由于升级机制未被广泛采用,因此自 RFC 9113 以来已弃用该机制。 它也不太适合用于规避审查,因为它涉及 HTTP/1.1 请求,该请求会被不支持 HTTP/2 的 HTTP 审查者捕获。

研究空白

在审查的背景下,HTTP/2 尚未得到广泛分析。 在这篇博文中,我们分析了 HTTP/2 作为审查规避技术的可行性,并展示了以下内容。

  1. HTTP/2 在中国和伊朗未受到审查,这两个国家广泛采用 HTTP/1.1 审查。
  2. 高达 6.28% 的服务器支持未加密的 HTTP/2,与大型网站相比,较小的服务器和受审查的域名显示出更高的支持。
  3. 大约 20% 的服务器仍然支持未加密的 HTTP/1.1。
  4. 为了轻松分析服务器对其未加密 HTTP 的支持,我们提供了工具 Does-It-Support-Unencrypted-Http

结果

在下文中,我们将展示未加密的 HTTP/2 在中国和伊朗未受到审查。 然后,我们将概述现有服务器对未加密的 HTTP/2 的支持。

审查

在中国,HTTP/1.1 的审查方式是组合使用不同的 TCP RST 数据包,具体取决于特定域名,这些数据包设置或未设置 ACK 标志。 在伊朗,HTTP/1.1 请求的审查方式是阻止页面、TCP RST 或空路由,具体取决于特定域名。 可以使用 curl 命令 curl http://nsfwyoutube.com --resolve nsfwyoutube.com:80:208.78.226.162 触发中国和伊朗的 HTTP/1.1 审查。 --resolve 标志可防止可能的 DNS 审查进行干扰。 虽然 HTTP/1.1 在中国和伊朗受到审查,但我们检测到具有预先知道的 HTTP/2 在这两个国家根本未受到审查。 对于通过 HTTP/1.1 审查的任何域名,在我们的评估中,等效的 HTTP/2 请求均未受到审查。 例如,curl --http2-prior-knowledge http://nsfwyoutube.com --resolve nsfwyoutube.com:80:208.78.226.162 访问的是这两个国家/地区通过 HTTP/1.1 审查的网站。 在中国和伊朗,可以访问任何支持未加密 HTTP/2 的服务器,而不会受到现有 HTTP 审查的干扰。

服务器支持

为了确定服务器对未加密 HTTP 的支持,我们测试了来自三个列表的域名:我们从 Tranco 前一百万、CitizenLab 中国测试列表 和 CitizenLab 伊朗测试列表 中选择了域名。 Tranco 前一百万列表包含在世界范围内流行的域名; Citizenlab 列表包含在相应国家/地区受到审查的域名。 某些域名无法解析或未打开 TCP 套接字; 我们将它们从评估中排除。 对于每个可访问的网站,我们使用 HTTP/1.1、HTTP/2 预先知道或 HTTP/2 升级机制在路径 / 上发送了一个 GET 请求。 我们遵循所有重定向到其他 HTTP 网站,并且如果服务器使用所需的 HTTP 版本响应了 200 OK,则认为该服务器支持所使用的 HTTP 版本。 下表显示了支持 HTTP/1.1、HTTP/2 预先知道和 HTTP/2 升级机制的域名数量。 列表 | HTTP/1.1 | HTTP/2 预先知道 | HTTP/2 升级机制 | 总计
---|---|---|---|---
Tranco Top 1M | 156 316 (18.62%) | 20 973 (2.50%) | 5227 (0.62%) | 839 393
CitizenLab China | 96 (19.35%) | 24 (4.84%) | 3 (0.60%) | 496
CitizenLab Iran | 161 (21.52%) | 47 (6.28%) | 13 (1.74%) | 749
下面,我们将详细介绍我们的测试向量以及服务器对我们评估的每个 HTTP 版本的支持。

未加密的 HTTP/1.1 支持

在未加密的 HTTP/1.1 支持扫描期间,我们为所有域名发送了以下测试向量:

GET / HTTP/1.1
Host: <domain_name>
User-Agent: Mozilla/5.0 (...) Gecko/20100101 Firefox/127.0
Connection: close

在三个使用的列表中,HTTP/1.1 的支持率在 18.62% 到 21.52% 之间变化。 这些结果表明,令人惊讶的是,许多域名仍然支持未加密的 HTTP/1.1。

支持未加密的 HTTP/2(预先知道)

在未加密的 HTTP/2(预先知道)扫描期间,我们首先发送了连接序言,然后为所有域名发送了以下测试向量:

GET / HTTP/2
Host: <domain_name>
User-Agent: Mozilla/5.0 (...) Gecko/20100101 Firefox/127.0

根据域名列表,对 HTTP/2(预先知道)的支持率在 2.5% 到 6.28% 之间变化。 重要的是,来自 CitizenLab 列表的受审查域名对 HTTP/2(预先知道)的支持率高于来自 Tranco 前一百万列表的流行域名。 这表明,虽然所有列表中对 HTTP/2(预先知道)的支持率都低于 HTTP/1.1,但相当多的受审查域名都支持未加密的 HTTP/2。

支持使用升级机制的未加密的 HTTP/2

在使用升级机制的未加密 HTTP/2 扫描期间,我们发送了以下 HTTP/1.1 请求作为所有域名的测试向量:

GET / HTTP/1.1
Host: <example.com>
User-Agent: Mozilla/5.0 (...) Gecko/20100101 Firefox/127.0
Connection: Upgrade, HTTP2-Settings
Upgrade: h2c
HTTP2-Settings: AAEAABAAAAIAAAABAAQAAP__AAUAAEAAAAgAAAA...

升级机制的支持率最低,范围为 0.6% 到 1.74%,具体取决于所使用的域名列表。 这并不奇怪,因为 RFC 9113 由于采用率低而弃用了此方法。

Tranco 关系

在所有扫描的 HTTP 版本中,Tranco 前一百万列表中对未加密 HTTP 的支持差异很大。 下面,我们描述了服务器对 Tranco 前一百万列表中不同 HTTP 版本的支持。 来自 Tranco 前一百万列表的服务器对未加密 HTTP 的支持。 来自 Tranco 前一百万列表的服务器对未加密 HTTP 的支持。 对于访问量较少的网站,未加密 HTTP/2 的支持有所增加,这与未加密 HTTP/1 相反。 有趣的是,对于较低的 Tranco 排名,未加密的 HTTP/2 支持有所增加,而未加密的 HTTP/1 支持增加到大约 400,000,然后再次减少。 这与 Citizenlab 列表中网站的支持一致,这些网站通常比 Tranco 网站小。 虽然总体上对 HTTP/2 的支持率较低,但我们认为它仍然可以用于成功访问某些被阻止的网站,并添加到规避审查技术的武器库中。

用于检测 HTTP 支持的工具

在我们的分析过程中,我们开发了一个工具来评估网站对未加密 HTTP 的支持。 下面,我们提供了 lgbtchinatour.com 的示例输出

lgbtchinatour.com 分析已开始。
服务器在线。 正在扫描!
#####################
HTTP/1.0:REDIRECT(www.lgbtchinatour.com/) -> SUCCESS
HTTP/1.1:SUCCESS
HTTP/2(预先知道):FAILURE
HTTP/2(升级):FAILURE

这表明 lgbtchinatour.com 在重定向后支持未加密的 HTTP/1.0 和未加密的 HTTP/1.1,但不支持任何未加密的 HTTP/2。 有关该工具功能的详细概述,请参阅 GitHub 项目。 我们希望我们的工具能够帮助社区和研究人员评估 HTTP 审查及其规避。

讨论

我们已成功绕过了中国和伊朗的 HTTP 审查者,并表明高达 6.28% 的受审查网站可以通过未加密的 HTTP/2 访问。 这仍然使超过 93% 的受审查网站无法通过未加密的 HTTP/2 作为规避方法访问。 尽管如此,我们认为未加密的 HTTP/2 是当前审查规避技术的宝贵补充,它加入了审查者和受影响人员之间的猫捉老鼠游戏。 下面,我们将讨论未加密的 HTTP/2 作为规避技术的局限性和潜力。

未加密的 HTTP/2 有什么特别之处?

HTTP/2 与以前的 HTTP 版本(如 HTTP/1.1)截然不同。 虽然包括 HTTP/1.1 在内的所有 HTTP 版本都由人类可读的 ASCII 字母组成,但 HTTP/2 是一种基于字节的协议。 这使得 HTTP/2 解析器与以前的 HTTP 解析器不兼容。 此外,HTTP/2 设计用于 HTTPS 中的加密使用。 允许未加密的使用,但未被宣传。 因此,浏览器不实现未加密的 HTTP/2。 我们怀疑这就是审查者不分析它的原因,也是审查规避社区忽略未加密 HTTP/2 的原因。

阻止未加密的 HTTP/2 的难度

与以前的 HTTP 版本相比,审查者可以阻止 HTTP/2,但面临更多挑战。 对于以前的 HTTP 版本,审查者可以分析客户端发送的第一条消息,以从人类可读的 ASCII 字节中提取连接的目的地。 在 HTTP/2 中,第一条消息不一定包含连接目的地,这迫使审查者持有额外的状态并解析其他消息。 HTTP/2 还利用了一种新的标头压缩形式,审查者必须适应。 我们怀疑在 HTTP/2 中添加的复杂性导致审查者决定不分析它。 我们强调,尽管 HTTP/2 复杂,审查者仍然可以实施 HTTP/2 审查。

使用未加密的 HTTP/2 绕过审查

实际上,将未加密的 HTTP/2 应用为审查规避技术是可能的,但存在挑战。 在这篇博文中,我们使用 curl 通过未加密的 HTTP/2 访问了原本被阻止的资源。 Curl 内置的对未加密 HTTP/2 的支持可用于访问特定的 HTML 网站,但与功能齐全的 Web 浏览器相比,其可用性有限。 遗憾的是,我们不知道有任何 Web 浏览器支持未加密的 HTTP/2。 为了从浏览器中使用未加密的 HTTP/2 作为审查规避技术,我们建议使用 HTTP 更新代理,该代理将浏览器发出的未加密的 HTTP/1.1 转换为未加密的 HTTP/2,反之亦然。 可以在防火墙的另一侧安装类似的代理,将未加密的 HTTP/2 降级为未加密的 HTTP/1.1,从而允许未加密的 HTTP/2 流量通过审查者并连接到仅支持未加密 HTTP/1.1 的服务器。 总的来说,我们认为 HTTP/2 作为审查规避方法的实际部署很困难,并且对可能的方法感兴趣。

结论

总之,我们通过访问中国和伊朗的被阻止资源,介绍了未加密的 HTTP/2 作为审查规避方法。 虽然服务器对未加密 HTTP/2 的支持率较低,但我们表明相当数量的受审查网站支持它。 为了帮助未来评估服务器对未加密 HTTP/2 的支持,我们开发了一个工具,并使其可以在 GitHub 上访问。 随意使用它或联系我们以进行进一步讨论和未来工作。 我们希望我们的贡献能够帮助受影响的人和审查规避社区。 请注意,未加密的 HTTP/2 不会保护您的流量; 在传输敏感数据时,请勿将其用作审查规避技术。

脚注

参考文献

  1. HTTP/1.1 [链接]Fielding, R., Nottingham, M. and Reschke, J., 2022.
  2. GET /out:自动发现应用层规避审查策略 [链接]Harrity, M., Bock, K., Sell, F. and Levin, D., 2022. 31st USENIX security symposium (USENIX security 22), pp. 465--483. USENIX Association.
  3. 通过准确的端到端测量了解全球审查的做法 [链接]Jin, L., Hao, S., Wang, H. and Cotton, C., 2021. Proceedings of the ACM on Measurement and Analysis of Computing Systems, Vol 5(3), pp. 43:1--43:25. DOI: 10.1145/3491055
  4. 检测和规避深度审查:伊朗协议白名单的案例研究 [链接]Bock, K., Fax, Y., Reese, K., Singh, J. and Levin, D., 2020. 10th USENIX workshop on free and open communications on the internet (FOCI 20). USENIX Association.
  5. 您的审查者是我的审查者:利用审查基础设施进行可用性攻击 [链接]Bock, K., Bharadwaj, P., Singh, J. and Levin, D., 2021. 2021 IEEE Security and Privacy Workshops (SPW), pp. 398--409. DOI: 10.1109/SPW53761.2021.00059
  6. HTTP/2 [链接]Thomson, M. and Benfield, C., 2022.
  7. 超文本传输协议版本 2 (HTTP/2) [链接]Belshe, M., Peon, R. and Thomson, M., 2015.

引用

@online{censors-ignore-unencrypted-http-2-traffic,
 author = {Lange, Felix and Niere, Niklas and von Niessen, Jonathan},
 title = {Censors Ignore Unencrypted HTTP/2 Traffic},
 year = 2024,
 url = {https://upb-syssec.github.io/blog/2024/http2/},
 urldate = {2025-04-10}
}

© Copyright 2025 System Security Group. Powered by Jekyll with al-folio theme. Hosted by GitHub Pages. Impressum. Last updated: April 10, 2025.