一 .什么是 web 缓存投毒
利用缓存机制保存恶意代码,让之后的用户访问同一缓存时遭受攻击
二.漏洞产生的原因:
未参与缓存键判断的可控输入被缓存并且该输入能影响响应那日容:攻击者能控制某个 http 请求的头部(如 host),查询参数,cookie 等,该输入被后端处理,反映在响应中(如后端从 host 请求某个前端文件,如果 host 可控,构造 attacker.com/js,将 host 值改为攻击者服务器,再在路径中写入攻击代码),但缓存系统没有将该输入纳入缓存键判断(后端仅将 url 路径纳入缓存键),就会导致不同用户的请求被认为为相同请求,然后返回攻击者事先注入的响应,导致中招
三.探测 web 缓存中毒
1.识别 unkeyed 输入
-
向请求头中添加额外的头部、参数、cookie,如 x-forwarded-host,x-original-url、x-url,x-forwarded-for,或自定义参数
-
查看输入的内容是否引起了响应内容的改变,若响应发生改变说明后端处理了输入的数据
-
判断是否将输入的参数纳入了缓存键,没有纳入缓存键才能使别的用户遭到攻击
-
即使纳入缓存键,但仍然可能存在缓存键参数的解析差异致使产生漏洞(如:host 常被纳入缓存键,但是某些缓存系统可能去掉端口号,不将端口号作为缓存键的一部分,这种不一致性导致漏洞)
2.尝试注入
-
确定存在可控输入,尝试输入攻击性代码影响响应内容,若能插入脚本,链接,重定向说明后端逻辑可控
-
输入必须要在处理后的响应结果中可见并且响应是可缓存的
3.辨别是否存在缓存
4.是否投毒成功?
四.常见攻击方式
1.http 头部注入,通过修改请求头部,使得缓存系统认为不同的请求是相同的,导致返回恶意响应
2.利用查询参数进行注入,利用查询参数或路径参数控制响应内容,常见于动态页面的生成,如搜索结果或产品列表
3.恶意 cookie 注入,当后端通过 cookie 来返回不同内容但又没有将 cookie 纳入缓存策略
五.防范
1.严格控制输入输出,对输入进行严格过滤,防止攻击性代码,如 xss 漏洞,对输入进行转义,避免直接处理
2.严格的缓存机制,对重要的涉及用户信息等的页面禁止缓存,添加 vary 头部,vary 头部根据不同用户的请求生成不同响应
3.严格的缓存键判别,将可能影响返回内容的参数都纳入缓存键
4.禁用不必要的 http 头部
缓存键缺陷:
1.未键控端口:host 存在缓存键中但是端口号被忽略,如果应用根据 host 重定向页面可将用户重定向到错误端口号造成 dos 攻击,如果允许非数字端口还可考虑 xss
2.未键控整个查询字符串
3.未键控单个查询字符串参数:如忽略掉 utm 参数
4.参数伪装:利用缓存解析 url 和后端服务器解析的不一致性将参数传递给应用又不进缓存
缓存只按&分割,只将keyed_param=abc 纳入缓存键
5.胖 get
6.资源导入里的动态内容:构造:GET /style.css?excluded_param=123);@import… 拼接后形成:@import url(/site.css?excluded_param=123);@import… 闭合掉前面的语句重新 import 我们想要注入的内容
7.缓存键规范化
8.缓存键注入
9.内部缓存中毒