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定义某些字符为分隔符(如分号或问号),但规范宽松,允许自定义实现添加字符。
常见源服务器分隔符:
-
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/indexvs/%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解析差异、分隔符处理和规范化不一致等问题。防御需要从密钥生成、缓存规则和输入验证等多方面入手,确保系统各组件行为一致,并对敏感信息实施严格的缓存控制。