Self XSS到存储型XSS
字数 1082 2025-08-27 12:33:42
从Self XSS到存储型XSS的升级利用分析
漏洞发现背景
本文分析了一个从Self XSS升级为存储型XSS的案例,涉及AngularJS模板注入技术。漏洞存在于一个名为redacted.com的网站中,通过电子邮件取消订阅功能实现了漏洞的升级。
漏洞发现过程
1. 初始探索
- 测试者在网站上花费数小时尝试XSS漏洞
- 发现即使找到XSS,由于网站正确编码输出,只能形成Self XSS
- 网站使用AngularJS框架
2. AngularJS模板注入发现
- 测试者阅读了关于AngularJS模板注入的文章后受到启发
- 尝试简单表达式
{{4*4}},发现某些位置未编码输出 - 确认存在XSS漏洞,但最初表现为Self XSS
3. 功能分析
网站具有以下关键功能:
- 电子邮件发送报告功能
- 可自定义报告名称
- 报告内容敏感,仅限认证用户查看
- 初始发现的XSS存在于报告名称中
4. 取消订阅链接发现
- 测试者发现邮件中包含取消订阅链接
- 该链接显示报告名称,且无需任何身份验证
- 报告名称在此处未经过滤输出
漏洞利用链
-
Self XSS阶段:
- 在报告名称字段注入AngularJS表达式
{{xss_payload}} - 仅影响攻击者自己的报告视图
- 在报告名称字段注入AngularJS表达式
-
升级为存储型XSS:
- 通过邮件发送包含恶意payload的报告
- 受害者点击取消订阅链接
- 恶意payload在受害者浏览器中执行
- 无需受害者认证,实现跨用户攻击
技术要点
AngularJS模板注入
- 当AngularJS表达式未被正确过滤时,可以执行任意JavaScript
- 基本测试payload:
{{4*4}}(应显示16) - 实际XSS payload可利用AngularJS的
$eval等功能
取消订阅链接特性
- 通常被视为低风险功能,安全措施较弱
- 常绕过常规的身份验证机制
- 提供了将私有内容公开化的途径
漏洞修复建议
- 对所有用户输入进行严格的输出编码
- 对AngularJS表达式进行过滤,特别是双大括号
{{}} - 取消订阅链接也应实施适当的访问控制
- 敏感内容不应通过低安全通道展示
经验总结
- 技术研究:了解目标使用的技术栈(如AngularJS)的特定漏洞
- 功能测试:全面测试所有功能点,包括看似次要的功能(如取消订阅)
- 漏洞升级:寻找将Self XSS转化为存储型XSS的途径
- 持续学习:通过阅读漏洞报告(如HackerOne)获取新思路
攻击Payload示例
{{constructor.constructor('alert(1)')()}}
或更复杂的XSS利用代码。
此案例展示了如何通过深入研究和功能链分析,将看似有限的Self XSS升级为影响广泛的存储型XSS漏洞。