特殊 HTTP 头部

Tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks

字典 & 工具

更改来源位置的头部

重写 IP source

  • X-Originating-IP: 127.0.0.1
  • X-Forwarded-For: 127.0.0.1
  • X-Forwarded: 127.0.0.1
  • Forwarded-For: 127.0.0.1
  • X-Forwarded-Host: 127.0.0.1
  • X-Remote-IP: 127.0.0.1
  • X-Remote-Addr: 127.0.0.1
  • X-ProxyUser-Ip: 127.0.0.1
  • X-Original-URL: 127.0.0.1
  • Client-IP: 127.0.0.1
  • X-Client-IP: 127.0.0.1
  • X-Host: 127.0.0.1
  • True-Client-IP: 127.0.0.1
  • Cluster-Client-IP: 127.0.0.1
  • Via: 1.0 fred, 1.1 127.0.0.1
  • Connection: close, X-Forwarded-For (检查 hop-by-hop headers)

重写 location

  • X-Original-URL: /admin/console
  • X-Rewrite-URL: /admin/console

逐跳 (Hop-by-Hop) 头部

逐跳头是指由当前处理请求的代理(proxy)处理并消费的头部,而不是端到端(end-to-end)头部。

  • Connection: close, X-Forwarded-For

hop-by-hop headers

HTTP Request Smuggling

  • Content-Length: 30
  • Transfer-Encoding: chunked

HTTP Request Smuggling / HTTP Desync Attack

Expect 头部

客户端可以发送 Expect: 100-continue,然后服务器可能响应 HTTP/1.1 100 Continue 来允许客户端继续发送请求体。但有些代理对这个头不太友好。

使用 Expect: 100-continue 的有趣结果:

  • 向服务器发送带有 body 的 HEAD 请求时,服务器没有考虑到 HEAD 请求不应有 body,因此保持连接打开直到超时。
  • 其他服务器在响应中返回奇怪数据:响应中包含从 socket 读取的随机数据、密钥,或者该行为甚至阻止了前端移除某些 header 值。
  • 它也导致过 0.CL desync:后端返回 400 而不是 100,前端 proxy 已准备好发送初始请求的 body,于是发送了该 body,后端将其视为新请求。
  • 发送 Expect: y 100-continue 的变体也导致 0.CL desync。
  • 类似地,当后端返回 404 时,会产生 CL.0 desync,因为恶意请求声明了 Content-Length,后端会把恶意请求及下一请求(受害者)的 Content-Length 字节一起读取/发送,这会使队列不同步:后端为恶意请求发送了 404 响应并随后发送了受害者请求的响应内容,但前端认为只发送了一个请求,因此第二个响应被错误地发给另一个受害者请求,依此类推。

关于 HTTP Request Smuggling 的更多信息请查看:

HTTP Request Smuggling / HTTP Desync Attack

缓存头部

服务器缓存头

  • X-Cache 在响应中可能为 miss(请求未被缓存)或 hit(已命中缓存)
  • Cf-Cache-Status 具有类似行为
  • Cache-Control 指示资源是否被缓存以及下次缓存的时长:Cache-Control: public, max-age=1800
  • Vary 常用于响应中,用来指示作为缓存键一部分的附加 header,即使这些 header 通常不被作为键。
  • Age 定义对象在代理缓存中存在的时间(秒)。
  • Server-Timing: cdn-cache; desc=HIT 也表示资源被缓存过。

Cache Poisoning and Cache Deception

本地缓存头

  • Clear-Site-Data: 指示应被清除的缓存类型:Clear-Site-Data: "cache", "cookies"
  • Expires: 包含响应应当过期的日期/时间:Expires: Wed, 21 Oct 2015 07:28:00 GMT
  • Pragma: no-cache 等同于 Cache-Control: no-cache
  • Warning: 通用的 HTTP Warning 头包含关于消息状态的可能问题的信息。响应中可能出现多个 Warning 头。示例:Warning: 110 anderson/1.3.37 "Response is stale"

条件请求

  • 使用 If-Modified-SinceIf-Unmodified-Since 的请求仅当响应头 Last-Modified 的时间不同才会返回数据。
  • 使用 If-MatchIf-None-Match 的条件请求使用 ETag 值,只有当数据(ETag)发生变化时,web 服务器才会发送响应内容。Etag 值来自 HTTP 响应。
  • Etag 值通常基于响应的内容计算。例如,ETag: W/"37-eL2g8DEyqntYlaLp5XLInBWsjWI" 表示 ETag 是 37 字节的 Sha1。

Range 请求

  • Accept-Ranges:指示服务器是否支持 range 请求,以及 range 可以用哪种单位表示。Accept-Ranges: <range-unit>
  • Range:指示服务器应返回文档的哪一部分。例如,Range:80-100 会返回原始响应的第 80 到 100 字节,并返回状态码 206 Partial Content。另请记得从请求中移除 Accept-Encoding 头。
  • 这在获取带有任意反射 javascript 代码(否则可能被转义)的响应时可能有用。但要滥用它,需要在请求中注入这些头。
  • If-Range:创建条件范围请求,仅在给定的 etag 或日期匹配远程资源时才满足。用于防止从不兼容版本的资源下载两个范围。
  • Content-Range:指示部分消息在完整消息体中的位置。

消息体信息

  • Content-Length:资源的大小,以十进制字节数表示。
  • Content-Type:指示资源的媒体类型
  • Content-Encoding:用于指定压缩算法。
  • Content-Language:描述面向受众的人类语言,以便根据用户的偏好进行区分。
  • Content-Location:指示返回数据的替代位置。

从 pentest 的角度来看,这些信息通常“无用”,但如果资源被 401 或 403 保护,而你能找到某种方式来获取这些信息,这可能会很有趣。
例如,在 HEAD 请求中结合 RangeEtag 可以通过 HEAD 请求 leak 页面内容:

  • 一个带有 Range: bytes=20-20 的请求,且响应包含 ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y",会 leak 第 20 字节的 SHA1 为 ETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y

服务器信息

  • Server: Apache/2.4.1 (Unix)
  • X-Powered-By: PHP/5.3.3

控制

  • Allow:此头用于告知资源可以处理的 HTTP 方法。例如,Allow: GET, POST, HEAD 表示资源支持这些方法。
  • Expect:客户端用此头传达服务器需要满足的期望以成功处理请求。常见用例包括 Expect: 100-continue,表示客户端打算发送大数据负载,并在发送前等待服务器返回 100 (Continue)。该机制有助于通过等待服务器确认来优化网络使用。

下载

  • 响应中的 Content-Disposition 头用于指示文件是应当以 inline(在网页内)显示,还是作为 attachment(下载)处理。例如:
Content-Disposition: attachment; filename="filename.jpg"

这意味着名为 “filename.jpg” 的文件将被下载并保存。

安全头

Content Security Policy (CSP)

Content Security Policy (CSP) Bypass

Trusted Types

通过在 CSP 中强制启用 Trusted Types,可以保护应用程序免受 DOM XSS 攻击。Trusted Types 确保只有经过专门构造并符合既定安全策略的对象,才能用于危险的 web API 调用,从而默认保护 JavaScript 代码的安全。

// Feature detection
if (window.trustedTypes && trustedTypes.createPolicy) {
// Name and create a policy
const policy = trustedTypes.createPolicy('escapePolicy', {
createHTML: str => str.replace(/\</g, '&lt;').replace(/>/g, '&gt;');
});
}
// Assignment of raw strings is blocked, ensuring safety.
el.innerHTML = "some string" // Throws an exception.
const escaped = policy.createHTML("<img src=x onerror=alert(1)>")
el.innerHTML = escaped // Results in safe assignment.

X-Content-Type-Options

该响应头可防止 MIME 类型嗅探,这种做法可能导致 XSS 漏洞。它确保浏览器遵循服务器指定的 MIME 类型。

X-Content-Type-Options: nosniff

X-Frame-Options

为防止 clickjacking,此响应头限制文档如何被嵌入 <frame><iframe><embed><object> 标签,建议所有文档明确指定其嵌入权限。

X-Frame-Options: DENY

跨来源资源策略 (CORP) 和 跨来源资源共享 (CORS)

CORP 对指定网站可以加载哪些资源至关重要,有助于减轻跨站点信息泄露。另一方面,CORS 提供了更灵活的跨来源资源共享机制,在某些条件下放宽同源策略。

Cross-Origin-Resource-Policy: same-origin
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true

跨源嵌入策略 (COEP) 和 跨源打开策略 (COOP)

COEP 和 COOP 对启用跨源隔离至关重要,可显著降低类似 Spectre 的攻击风险。它们分别控制跨源资源的加载以及与跨源窗口的交互。

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin-allow-popups

HTTP Strict Transport Security (HSTS)

最后,HSTS 是一项安全功能,强制浏览器仅通过安全的 HTTPS 连接与服务器通信,从而增强隐私和安全性。

Strict-Transport-Security: max-age=3153600

Permissions-Policy (以前称为 Feature-Policy)

Permissions-Policy 允许 web 开发者在文档内有选择地启用、禁用或修改某些浏览器功能和 API 的行为。它是已弃用的 Feature-Policy header 的继任者。此 header 通过限制对可能被滥用的强大功能的访问来减少攻击面。

Permissions-Policy: geolocation=(), camera=(), microphone=()

常见指令:

Directive描述
accelerometer控制对加速度计传感器的访问
camera控制对视频输入设备(网络摄像头)的访问
geolocation控制对 Geolocation API 的访问
gyroscope控制对陀螺仪传感器的访问
magnetometer控制对磁力计传感器的访问
microphone控制对音频输入设备的访问
payment控制对 Payment Request API 的访问
usb控制对 WebUSB API 的访问
fullscreen控制对 Fullscreen API 的访问
autoplay控制媒体是否可以自动播放
clipboard-read控制对读取剪贴板内容的访问
clipboard-write控制对写入剪贴板的访问

语法值:

  • () - 完全禁用该功能
  • (self) - 仅允许同源使用该功能
  • * - 允许所有来源使用该功能
  • (self "https://example.com") - 允许同源及指定域名使用

示例配置:

# Restrictive policy - disable most features
Permissions-Policy: geolocation=(), camera=(), microphone=(), payment=(), usb=()

# Allow camera only from same origin
Permissions-Policy: camera=(self)

# Allow geolocation for same origin and a trusted partner
Permissions-Policy: geolocation=(self "https://maps.example.com")

从安全角度来看,缺失或过于宽松的 Permissions-Policy 头可能允许攻击者(例如通过 XSS 或嵌入的 iframes)滥用浏览器的强大功能。请始终将功能限制为应用所需的最低范围。

头部名称大小写绕过

HTTP/1.1 将 header 字段名定义为 不区分大小写(RFC 9110 §5.1)。然而,常见的情况是自定义中间件、安全过滤器或业务逻辑在比较接收到的 字面 header 名时没有先规范化大小写(例如 header.equals("CamelExecCommandExecutable"))。如果这些检查以 区分大小写 的方式执行,攻击者可以通过发送同名但大小写不同的 header 来绕过它们。

典型出现此错误的场景:

  • 尝试在请求到达敏感组件之前阻止“危险”内部 header 的自定义允许/拒绝 列表。
  • 内部实现的 reverse-proxy 伪 header(例如 X-Forwarded-For)的清理/消毒。
  • 暴露管理/调试端点并依赖 header 名称进行认证或命令选择的框架实现。

利用该绕过

  1. 识别在服务器端被过滤或校验的 header(例如通过阅读源代码、文档或错误信息)。
  2. 发送 相同但大小写不同的 header(混合大小写或全大写)。因为 HTTP 栈通常仅在用户代码运行后才对 header 规范化,所以脆弱的检查可能会被跳过。
  3. 如果下游组件以不区分大小写的方式处理 header(大多数如此),它将接受攻击者控制的值。

示例:Apache Camel exec RCE (CVE-2025-27636)

在易受攻击的 Apache Camel 版本中,Command Center 路由试图通过剥离 CamelExecCommandExecutableCamelExecCommandArgs 这些 header 来阻止不受信任的请求。比较是用 equals() 完成的,因此只有精确的小写名称才会被移除。

# Bypass the filter by using mixed-case header names and execute `ls /` on the host
curl "http://<IP>/command-center" \
-H "CAmelExecCommandExecutable: ls" \
-H "CAmelExecCommandArgs: /"

这些 header 未经过滤就到达 exec 组件,导致 remote command execution,并以 Camel 进程的权限执行远程命令。

检测与缓解

  • 在执行允许/拒绝比较 之前,将所有 header 名称规范化为统一大小写(通常为小写)。
  • 拒绝可疑的重复项:如果同时存在 Header:HeAdEr:,将其视为异常。
  • 使用正向允许列表,并在规范化 之后 强制执行。
  • 对管理端点实施认证并进行网络分段隔离。

References

Tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks