◈ 渗透任务
SPA 单页应用前端安全审计
任务中
你的身份
「暗影安全公司」渗透测试工程师
目标网站
QuickApp SPA 应用 (app.quickapp.example.com)
委托方
QuickApp 开发团队 — 安全审计发现前端路由处理可能存在漏洞
任务目标
验证 URL hash 是否存在 DOM XSS 漏洞
- 通过修改 URL 的 # 部分注入 XSS payload
- payload 通过 innerHTML 渲染触发
◈ 教程:什么是 DOM 型 XSS?
原理
DOM 型 XSS(DOM-based XSS)的漏洞完全存在于客户端 JavaScript中。 恶意数据不经过服务器,而是在浏览器端通过 JavaScript 直接从 Source 流向 Sink。
Source/Sink 模型:Source 是用户可控的数据入口,Sink 是危险的 DOM 操作。
当 Source 的数据未经处理直接到达 Sink,就产生了 DOM XSS。
与反射型/存储型的区别
- 反射型/存储型:服务端将数据嵌入 HTML 后返回给浏览器
- DOM 型:服务端返回的 HTML 是正常的,由客户端 JS 动态修改 DOM 导致漏洞
- 关键区别:DOM XSS 的恶意数据不经过 HTTP 响应,服务端完全无感知
常见 Source
location.hash— URL 的 # 部分location.search— URL 的 ? 参数部分document.referrer— 来源页面 URLwindow.name— 窗口名称postMessage— 跨窗口消息
常见 Sink
innerHTML— 设置元素的 HTML 内容(最常见)outerHTML— 替换整个元素document.write()— 直接写入文档流eval()— 执行 JavaScript 字符串location.href— 页面跳转
漏洞代码分析
// Source: 从 URL hash 获取用户输入
var hash = location.hash.substring(1);
// Sink: 直接写入 innerHTML(危险!)
element.innerHTML = decodeURIComponent(hash);
// 为什么 innerHTML 危险?
// 它会将字符串当作 HTML 解析,包括标签和事件处理器
◈ 练习:触发 DOM 型 XSS
目标:QuickApp SPA 应用 (app.quickapp.example.com) 的页面 JavaScript 会读取 URL 的
# 后面的内容,
并通过 innerHTML 写入 DOM。你的任务是构造包含恶意代码的 hash。
(无 hash 值)
DOM 渲染输出区域(innerHTML Sink):
修改 URL 的 # 部分,内容将在此渲染...
查看漏洞源码 (JavaScript)
// JavaScript 代码(客户端)
// 读取 URL hash 并直接写入 innerHTML
window.onload = function() {
var hash = location.hash.substring(1); // 去掉 # 号
if (hash) {
// 危险:用户可控数据直接写入 innerHTML
document.getElementById("output").innerHTML = decodeURIComponent(hash);
}
};
// HTML 结构
// <div id="output"></div>
过滤状态:无任何过滤 — URL hash 经 decodeURIComponent 解码后直接写入 innerHTML