Web缓存漏洞:利用与防御全解析
字数 1798 2025-08-30 06:50:12

Web缓存漏洞:利用与防御全解析

1. 背景介绍

网络缓存技术自互联网诞生之初就已存在,通过使用密钥对请求进行指纹识别来工作。密钥通常基于请求URL的某些或全部部分构建,并将密钥与存储的静态响应进行映射。

现代生产系统主要通过内容分发网络(CDN)实现缓存,如CloudFlare、Akamai或CloudFront等提供商。CDN可视为全球分布的网络缓存代理网络,提供静态响应以提高系统效率和可扩展性。

2. 缓存攻击类型

2.1 网络缓存中毒

定义:当攻击者能够存储带有恶意负载的消息,使其匹配错误的密钥时发生。

关键点

  • 依赖于密钥生成过程
  • 相同指纹的每个请求应生成相同响应
  • 如果响应根据特定标头值变化,该值应包含在密钥中

2.2 网络缓存欺骗

定义:当攻击者构造恶意请求,检索并缓存用户数据时发生。

关键点

  • 依赖于缓存规则分析
  • 可能导致存储包含敏感信息的动态响应
  • 可能劫持令牌和API密钥,导致账户接管

3. URL解析差异

源服务器必须提取请求资源的绝对路径来评估缓存规则、计算缓存密钥和映射端点处理器。这通过路径分隔符和规范化完成。

风险点:当缓存和应用服务器的解析器不同时,可能利用这种差异改变URL含义。

3.1 分隔符差异

RFC定义某些字符为分隔符(如分号或问号),但规范宽松,允许自定义实现添加字符。

常见源服务器分隔符:

  1. Spring框架

    • 使用分号作为分隔符包含矩阵变量
    • 示例:/MyAccount;var1=val → 路径:/MyAccount
  2. Ruby on Rails

    • 使用点字符作为格式化扩展名分隔符
    • 示例:/MyAccount.html → 路径:/MyAccount
  3. OpenLiteSpeed

    • 使用空字节编码作为分隔符
    • 示例:/MyAccount%00aaa → 路径:/MyAccount
  4. Nginx

    • 使用编码的换行字节作为分隔符(特定配置下)
    • 示例:/users/MyAccount%0aaaa → 路径:/account/MyAccount

3.2 检测源分隔符方法

  1. 识别一个不可缓存的请求(如POST方法或带有Cache-Control: no-store的响应)
  2. 发送相同请求但在路径末尾附加随机后缀
  3. 发送相同请求但在随机后缀前包含潜在分隔符
  4. 比较响应是否相同

自动化测试:可使用Burp Intruder和包含所有ASCII字符的字典,测试字符的未编码和URL编码版本。

3.3 检测缓存分隔符方法

  1. 识别一个可缓存的请求(通过响应时间或X-Cache: hit头)
  2. 发送相同请求但在URL路径后缀后加上可能的分隔符和随机值
  3. 比较响应是否相同

4. 规范化问题

缓存和源服务器都使用URL解析器提取路径,用于端点映射、缓存密钥和规则生成。

4.1 编码问题

URI RFC定义了URL编码,允许对字符进行编码以避免修改路径名含义。

问题:许多HTTP服务器和代理在解释路径前会解码某些分隔符字符,且过程不一致。

示例

  • /myAccount%3Fparam/myAccount?param
  • 代理可能解码URL并转发带有解码值的消息

4.2 检测解码行为方法

  1. 比较基础请求与其编码版本
    • 示例:/home/index vs /%68%6f%6d%65%2f%69%6e%64%65%78
  2. 如果响应相同且未从缓存获取,则源服务器解码了路径
  3. 对于可缓存请求,可检测缓存解析器的解码行为

5. 防御措施

5.1 针对缓存中毒

  1. 确保密钥生成包含所有可能影响响应的元素
  2. 验证所有用户输入,特别是影响缓存密钥的部分
  3. 实施严格的缓存控制头

5.2 针对缓存欺骗

  1. 避免缓存包含敏感信息的动态响应
  2. 为敏感端点设置Cache-Control: privateno-store
  3. 实施适当的认证和授权检查

5.3 通用防御

  1. 确保源服务器和缓存服务器使用相同的URL解析规则
  2. 定期进行安全审计和渗透测试
  3. 监控异常缓存行为
  4. 保持所有组件(CDN、代理、服务器)更新到最新版本

6. 总结

Web缓存漏洞主要分为中毒和欺骗两类,利用URL解析差异、分隔符处理和规范化不一致等问题。防御需要从密钥生成、缓存规则和输入验证等多方面入手,确保系统各组件行为一致,并对敏感信息实施严格的缓存控制。

Web缓存漏洞:利用与防御全解析 1. 背景介绍 网络缓存技术自互联网诞生之初就已存在,通过使用密钥对请求进行指纹识别来工作。密钥通常基于请求URL的某些或全部部分构建,并将密钥与存储的静态响应进行映射。 现代生产系统主要通过内容分发网络(CDN)实现缓存,如CloudFlare、Akamai或CloudFront等提供商。CDN可视为全球分布的网络缓存代理网络,提供静态响应以提高系统效率和可扩展性。 2. 缓存攻击类型 2.1 网络缓存中毒 定义 :当攻击者能够存储带有恶意负载的消息,使其匹配错误的密钥时发生。 关键点 : 依赖于密钥生成过程 相同指纹的每个请求应生成相同响应 如果响应根据特定标头值变化,该值应包含在密钥中 2.2 网络缓存欺骗 定义 :当攻击者构造恶意请求,检索并缓存用户数据时发生。 关键点 : 依赖于缓存规则分析 可能导致存储包含敏感信息的动态响应 可能劫持令牌和API密钥,导致账户接管 3. URL解析差异 源服务器必须提取请求资源的绝对路径来评估缓存规则、计算缓存密钥和映射端点处理器。这通过路径分隔符和规范化完成。 风险点 :当缓存和应用服务器的解析器不同时,可能利用这种差异改变URL含义。 3.1 分隔符差异 RFC定义某些字符为分隔符(如分号或问号),但规范宽松,允许自定义实现添加字符。 常见源服务器分隔符: Spring框架 : 使用分号作为分隔符包含矩阵变量 示例: /MyAccount;var1=val → 路径: /MyAccount Ruby on Rails : 使用点字符作为格式化扩展名分隔符 示例: /MyAccount.html → 路径: /MyAccount OpenLiteSpeed : 使用空字节编码作为分隔符 示例: /MyAccount%00aaa → 路径: /MyAccount Nginx : 使用编码的换行字节作为分隔符(特定配置下) 示例: /users/MyAccount%0aaaa → 路径: /account/MyAccount 3.2 检测源分隔符方法 识别一个不可缓存的请求(如POST方法或带有 Cache-Control: no-store 的响应) 发送相同请求但在路径末尾附加随机后缀 发送相同请求但在随机后缀前包含潜在分隔符 比较响应是否相同 自动化测试 :可使用Burp Intruder和包含所有ASCII字符的字典,测试字符的未编码和URL编码版本。 3.3 检测缓存分隔符方法 识别一个可缓存的请求(通过响应时间或 X-Cache: hit 头) 发送相同请求但在URL路径后缀后加上可能的分隔符和随机值 比较响应是否相同 4. 规范化问题 缓存和源服务器都使用URL解析器提取路径,用于端点映射、缓存密钥和规则生成。 4.1 编码问题 URI RFC定义了URL编码,允许对字符进行编码以避免修改路径名含义。 问题 :许多HTTP服务器和代理在解释路径前会解码某些分隔符字符,且过程不一致。 示例 : /myAccount%3Fparam → /myAccount?param 代理可能解码URL并转发带有解码值的消息 4.2 检测解码行为方法 比较基础请求与其编码版本 示例: /home/index vs /%68%6f%6d%65%2f%69%6e%64%65%78 如果响应相同且未从缓存获取,则源服务器解码了路径 对于可缓存请求,可检测缓存解析器的解码行为 5. 防御措施 5.1 针对缓存中毒 确保密钥生成包含所有可能影响响应的元素 验证所有用户输入,特别是影响缓存密钥的部分 实施严格的缓存控制头 5.2 针对缓存欺骗 避免缓存包含敏感信息的动态响应 为敏感端点设置 Cache-Control: private 或 no-store 实施适当的认证和授权检查 5.3 通用防御 确保源服务器和缓存服务器使用相同的URL解析规则 定期进行安全审计和渗透测试 监控异常缓存行为 保持所有组件(CDN、代理、服务器)更新到最新版本 6. 总结 Web缓存漏洞主要分为中毒和欺骗两类,利用URL解析差异、分隔符处理和规范化不一致等问题。防御需要从密钥生成、缓存规则和输入验证等多方面入手,确保系统各组件行为一致,并对敏感信息实施严格的缓存控制。