diff --git a/src/network-services-pentesting/pentesting-web/special-http-headers.md b/src/network-services-pentesting/pentesting-web/special-http-headers.md index 9ef17b658..5a9bd5162 100644 --- a/src/network-services-pentesting/pentesting-web/special-http-headers.md +++ b/src/network-services-pentesting/pentesting-web/special-http-headers.md @@ -2,12 +2,12 @@ {{#include ../../banners/hacktricks-training.md}} -## 字典和工具 +## 字典 & 工具 - [https://github.com/danielmiessler/SecLists/tree/master/Miscellaneous/Web/http-request-headers](https://github.com/danielmiessler/SecLists/tree/master/Miscellaneous/Web/http-request-headers) - [https://github.com/rfc-st/humble](https://github.com/rfc-st/humble) -## 更改位置的头 +## 用于修改来源/位置的 Headers 重写 **IP 源**: @@ -26,110 +26,132 @@ - `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` (检查逐跳头) +- `Connection: close, X-Forwarded-For` (检查 hop-by-hop headers) 重写 **位置**: - `X-Original-URL: /admin/console` - `X-Rewrite-URL: /admin/console` -## 逐跳头 +## Hop-by-Hop headers -逐跳头是设计用于由当前处理请求的代理处理和消费的头,与端到端头相对。 +Hop-by-hop header 是设计用来由当前处理请求的代理解析和消费的 header,与端到端 header 不同。 - `Connection: close, X-Forwarded-For` + {{#ref}} ../../pentesting-web/abusing-hop-by-hop-headers.md {{#endref}} -## HTTP 请求走私 +## HTTP Request Smuggling - `Content-Length: 30` - `Transfer-Encoding: chunked` + {{#ref}} ../../pentesting-web/http-request-smuggling/ {{#endref}} -## 缓存头 +## The Expect header -**服务器缓存头**: +客户端可能会发送头 `Expect: 100-continue`,然后服务器可以返回 `HTTP/1.1 100 Continue` 以允许客户端继续发送请求体。然而,有些代理不太喜欢这个 header。 + +`Expect: 100-continue` 的有趣结果包括: +- 向服务器发送带有 body 的 HEAD 请求,服务器没有考虑到 HEAD 请求不应有 body,导致连接保持打开直到超时。 +- 有些服务器在响应中返回奇怪的数据:从 socket 读取到的随机数据、密钥,甚至可以阻止前端移除某些 header 值。 +- 这还可能引发 `0.CL` desync,因为后端返回了 400 响应而不是 100 响应,但代理前端已经准备好发送初始请求的 body,于是发送了它,后端将其当作新请求处理。 +- 发送 `Expect: y 100-continue` 变体也引发过 `0.CL` desync。 +- 类似的错误中,后端返回 404 导致 `CL.0` desync:恶意请求指示了一个 `Content-Length`,因此后端会把恶意请求和下一个请求(受害者)的 `Content-Length` 字节一起发送,这使得队列不同步 —— 后端为恶意请求发送了 404 响应加上受害者请求的响应,但前端认为只发送了 1 个请求,因此第二个响应被发给了第二个受害者请求,依此类推...... + +有关 HTTP Request Smuggling 的更多信息请参见: + +{{#ref}} +../../pentesting-web/http-request-smuggling/ +{{#endref}} + + +## 缓存相关 Headers + +Server Cache Headers: + +- **`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`** 也表明资源被缓存 -- **`X-Cache`** 在响应中可能具有值 **`miss`** 当请求未被缓存时,值 **`hit`** 当它被缓存时 -- 在头 **`Cf-Cache-Status`** 中有类似的行为 -- **`Cache-Control`** 指示资源是否被缓存以及下次资源将被缓存的时间:`Cache-Control: public, max-age=1800` -- **`Vary`** 通常在响应中使用,以 **指示额外的头**,这些头被视为 **缓存键的一部分**,即使它们通常没有键。 -- **`Age`** 定义对象在代理缓存中存在的时间(以秒为单位)。 -- **`Server-Timing: cdn-cache; desc=HIT`** 也指示资源已被缓存 {{#ref}} ../../pentesting-web/cache-deception/ {{#endref}} -**本地缓存头**: +Local Cache headers: -- `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`: **`Warning`** 一般 HTTP 头包含有关消息状态可能存在问题的信息。响应中可能出现多个 `Warning` 头。`Warning: 110 anderson/1.3.37 "Response is stale"` +- `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 header,包含有关消息状态可能问题的信息。响应中可能出现多个 `Warning` header。例:`Warning: 110 anderson/1.3.37 "Response is stale"` ## 条件请求 -- 使用这些头的请求:**`If-Modified-Since`** 和 **`If-Unmodified-Since`** 仅在响应头 **`Last-Modified`** 包含不同时间时才会返回数据。 -- 使用 **`If-Match`** 和 **`If-None-Match`** 的条件请求使用 Etag 值,因此如果数据(Etag)已更改,Web 服务器将发送响应的内容。`Etag` 是从 HTTP 响应中获取的。 -- **Etag** 值通常是 **基于** 响应的 **内容** 计算的。例如,`ETag: W/"37-eL2g8DEyqntYlaLp5XLInBWsjWI"` 表示 `Etag` 是 **37 字节** 的 **Sha1**。 +- 使用这些 header 的请求:**`If-Modified-Since`** 和 **`If-Unmodified-Since`** 仅在响应头 **`Last-Modified`** 包含不同时间时才返回数据。 +- 使用 **`If-Match`** 和 **`If-None-Match`** 的条件请求使用 Etag 值,只有当数据(Etag)已更改时,web 服务器才会发送响应内容。`Etag` 来自 HTTP 响应。 +- **Etag** 值通常基于响应的**内容**计算。例如,`ETag: W/"37-eL2g8DEyqntYlaLp5XLInBWsjWI"` 表示该 Etag 是 **37 字节** 的 **SHA1**。 -## 范围请求 +## Range 请求 -- **`Accept-Ranges`**: 指示服务器是否支持范围请求,如果支持,则以哪种单位表示范围。`Accept-Ranges: ` -- **`Range`**: 指示服务器应返回文档的部分。例如,`Range:80-100` 将返回原始响应的字节 80 到 100,状态码为 206 部分内容。还要记得从请求中删除 `Accept-Encoding` 头。 -- 这可能有助于获取包含任意反射 JavaScript 代码的响应,否则可能会被转义。但要滥用这一点,您需要在请求中注入这些头。 -- **`If-Range`**: 创建一个条件范围请求,仅在给定的 etag 或日期与远程资源匹配时满足。用于防止从不兼容版本的资源下载两个范围。 -- **`Content-Range`**: 指示部分消息在完整消息体中的位置。 +- **`Accept-Ranges`**:指示服务器是否支持 range 请求,以及可以用哪种单位表达范围。`Accept-Ranges: ` +- **`Range`**:指示服务器应返回文档的哪一部分。例如,`Range:80-100` 将返回原始响应的第 80 到 100 字节,并返回状态码 206 Partial Content。也请记得从请求中移除 `Accept-Encoding` header。 +- 这在获取包含任意反射 JavaScript 代码(否则会被转义)的响应时可能有用。但要滥用它,需要在请求中注入这些 header。 +- **`If-Range`**:创建一个有条件的 range 请求,只有在给定的 etag 或日期匹配远端资源时才会被满足。用于防止从资源的不兼容版本下载两个范围。 +- **`Content-Range`**:指示部分消息在完整消息中的位置。 ## 消息体信息 -- **`Content-Length`:** 资源的大小,以字节的十进制数表示。 +- **`Content-Length`:** 资源的大小,以十进制字节数表示。 - **`Content-Type`**: 指示资源的媒体类型 - **`Content-Encoding`**: 用于指定压缩算法。 -- **`Content-Language`**: 描述面向受众的人类语言,以便用户可以根据自己的首选语言进行区分。 -- **`Content-Location`**: 指示返回数据的替代位置。 +- **`Content-Language`**: 描述面向受众的人类语言,以便用户根据自己的偏好区分语言。 +- **`Content-Location`**: 指示返回数据的备用位置。 -从渗透测试的角度来看,这些信息通常是“无用的”,但如果资源受到 401 或 403 的 **保护**,并且您可以找到某种 **方法** 来 **获取** 这些 **信息**,这可能是 **有趣的**。\ -例如,在 HEAD 请求中结合 **`Range`** 和 **`Etag`** 可以通过 HEAD 请求泄露页面的内容: +从 pentest 的角度看这些信息通常“没用”,但如果资源被 401 或 403 保护且你能找到某种方式去获取这些信息,这可能很有趣。\ +例如,`Range` 和 `Etag` 在 HEAD 请求中的组合可以通过 HEAD 请求 leak 页面内容: -- 带有头 `Range: bytes=20-20` 的请求和包含 `ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"` 的响应泄露了字节 20 的 SHA1 为 `ETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y` +- 带有头 `Range: bytes=20-20` 的请求且响应包含 `ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"`,泄露出字节 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)` 响应。此机制有助于通过等待服务器确认来优化网络使用。 +- **`Allow`**: 该 header 用于指示资源可处理的 HTTP 方法。例如,`Allow: GET, POST, HEAD` 表示该资源支持这些方法。 +- **`Expect`**: 客户端用来传达服务器在处理请求时需要满足的期望。一个常见用例是 `Expect: 100-continue`,表示客户端打算发送大量数据负载。客户端会等待 `100 (Continue)` 响应再继续发送,从而优化网络使用。 ## 下载 -- **`Content-Disposition`** 头在 HTTP 响应中指示文件应显示为 **内联**(在网页内)还是作为 **附件**(下载)。例如: +- HTTP 响应中的 **`Content-Disposition`** header 指示文件是应内联显示(inline,页面内)还是作为附件(attachment,下载)处理。例如: ``` Content-Disposition: attachment; filename="filename.jpg" ``` -这意味着名为 "filename.jpg" 的文件旨在被下载和保存。 +这意味着名为 "filename.jpg" 的文件应被下载并保存。 -## 安全头部 +## 安全标头 ### 内容安全策略 (CSP) + {{#ref}} ../../pentesting-web/content-security-policy-csp-bypass/ {{#endref}} -### **受信任的类型** +### **Trusted Types** -通过 CSP 强制实施受信任的类型,应用程序可以防止 DOM XSS 攻击。受信任的类型确保只有符合既定安全政策的特定构造对象可以用于危险的 Web API 调用,从而默认保护 JavaScript 代码。 +通过在 CSP 中强制使用 Trusted Types,应用可以免受 DOM XSS 攻击。Trusted Types 确保只有符合既定安全策略、专门构造的对象才能用于危险的 web API 调用,从而默认保护 JavaScript 代码。 ```javascript // Feature detection if (window.trustedTypes && trustedTypes.createPolicy) { @@ -148,75 +170,75 @@ el.innerHTML = escaped // Results in safe assignment. ``` ### **X-Content-Type-Options** -此头部防止 MIME 类型嗅探,这是一种可能导致 XSS 漏洞的做法。它确保浏览器尊重服务器指定的 MIME 类型。 +此响应头可防止 MIME 类型嗅探,这种做法可能导致 XSS 漏洞。它确保浏览器遵守服务器指定的 MIME 类型。 ``` X-Content-Type-Options: nosniff ``` ### **X-Frame-Options** -为了对抗点击劫持,此头部限制了文档如何嵌入在 ``、`