Marginwidth/marginheight – 意想不到的跨源通信通道
字数 1331 2025-08-19 12:41:11
Marginwidth/marginheight – 意想不到的跨源通信通道
概述
本文介绍了一种利用HTML规范中marginwidth和marginheight属性实现跨源通信的非传统方法。这种方法在安全研究和XSS挑战中具有特殊价值,因为它提供了一种鲜为人知的跨域通信途径。
核心发现
背景故事
2020年7月6日发布的XSS挑战中,只有四人能够解决,解决方案涉及使用marginwidth/marginheight属性。挑战的核心代码如下:
document.addEventListener("DOMContentLoaded", () => {
for (let attr of document.body.attributes) {
eval(attr.value);
}
});
这段代码会遍历<body>元素的所有属性,并将属性值作为JavaScript执行。挑战的关键在于找到一种方法将任意属性注入到document.body中。
HTML规范中的发现
HTML规范第14部分"渲染"中规定:
- 如果
<body>标签拥有marginheight属性,它将映射到CSS的margin-top属性 - 如果不存在该属性,则检查
topmargin属性 - 如果都不存在,且页面位于嵌套的浏览器上下文(如
<frame>或<iframe>)中,浏览器将使用容器元素的marginwidth属性
关键点:这种现象在跨域情况下也被规范直接允许。
浏览器实现差异
Chromium
marginwidth属性反映在<body>元素中,但会被强制转换为整数- 会监听属性值的动态更改
- 示例代码:
<style>
iframe, input {
width:400px;
}
</style>
<iframe id=ifr src="https://example.com" marginwidth="0"></iframe>
<br>
<input type=range
min=0
max=500
value=0
oninput="ifr.setAttribute('marginwidth', this.value)">
Firefox
<iframe marginwidth>值不会反映在嵌套文档DOM树中- 但可以通过
getComputedStyle()获取 - 滑块示例与Chromium工作方式相同
Safari
<iframe marginwidth>值无需修改即可反映在嵌套<body>元素中- 不会监听属性更改,因此动态修改无效
XSS挑战解决方案
解决方案非常简单:
<iframe src="https://securitymb.github.io/xss/3"
marginwidth="alert(document.domain)">
提示:使用Safari可能会更容易解决此挑战。
作为跨域通信通道
marginwidth/marginheight可以作为跨域通信通道,不同浏览器实现方式不同:
-
Safari:
- 父元素设置
marginwidth - 子元素观察
<body>的marginwidth
- 父元素设置
-
Chrome:
- 父级逐字节设置
marginwidth - 子级观察
<body marginwidth>属性变化
- 父级逐字节设置
-
Firefox:
- 父级逐字节设置
marginwidth - 子元素观察
getComputedStyle(document.body).marginLeft
- 父级逐字节设置
安全意义
- HTML规范中仍存在许多隐藏特性,可能在某些特殊攻击场景中被利用
marginwidth特别适合XS-Leaking(跨站泄漏)漏洞,尽管目前尚未找到可行方案- 展示了非传统跨域通信方法的可能性
总结
本文揭示了HTML规范中一个鲜为人知的特性,展示了如何利用marginwidth/marginheight属性实现跨源通信。不同浏览器的实现差异为安全研究和漏洞利用提供了新的思路。这种技术不仅适用于XSS挑战,也可能在未来的安全研究中发挥重要作用。
关键收获:深入理解HTML规范中的边缘特性可以为安全研究提供新的攻击面和防御思路。