目录
代码展示:
<script>
const data = decodeURIComponent(location.hash.substr(1));;
const root = document.createElement('div');
root.innerHTML = data;
// 这里模拟了XSS过滤的过程,方法是移除所有属性,sanitizer
for (let el of root.querySelectorAll('*')) {
let attrs = [];
for (let attr of el.attributes) {
attrs.push(attr.name);
}
for (let name of attrs) {
el.removeAttribute(name);
}
}
document.body.appendChild(root);
</script>
题目分析:可以看到这是个明显的DOM XSS,用户的输入会构成一个新div元素的子结点,但在插入body之前会被移除所有的属性(例如:<img src=x οnerrοr=alert(1)> 经过上述代码过滤后会变为<img>,使得我们传入的数据失效)
解法一:绕过过滤-DOM clobbering
DOM clobbering的介绍
DOM clobbering主要是用来进行DOM型的XSS攻击,其可以篡改JS函数原本的属性恶意插入一些XSS代码到页面的JS中去,它的特征就是利用了元素配置id或name属性后可以使用包括document、window、自己名称的形式进行访问(假如我们写了一个a标签,给他了一个id和name,那么我们就可以通过id或name来拿到这个a标签)。其可以对document的属性进行恶意的替换。特别是在元素的属性名与JavaScript全局对象的属性名冲突时,可能会破坏正常的DOM操作或脚本运行从而影响dom树的结构造成破坏。也是这一特性让它有了DOM COLBBERING这个名号。
DOM clobbering原理
DOM clobbering(文档对象模型覆写)的原理主要涉及利用特定的 HTML 标签属性或结构来影响和篡改网页的 DOM 环境中的已有元素或变量。
一、利用标签属性影响全局变量引用
- 通过自定义属性影响全局对象属性:
- 在 HTML 中,某些标签支持自定义属性。例如,
<a>
、<img>
、<iframe>
等标签可以添加自定义的属性名称。当这些标签的自定义属性名称与 JavaScript 中已存在的全局变量或全局对象的属性名称相同时,就有可能引发 DOM clobbering。- 利用表单元素属性影响全局变量:
- HTML 中的表单元素,如
<input>
、<select>
、<textarea>
等,它们的name
和id
属性也可能引发类似的问题。如果表单元素的name
或id
属性值与已有的全局变量名称相同,同样可能导致全局变量被意外覆写。
二、利用特定标签结构影响 DOM 树的引用关系
- 利用命名冲突改变引用指向:
- 除了属性名称的冲突外,标签的命名本身也可能引发问题。例如,如果网页中有一个使用了
document.getElementById('myElement')
来获取一个特定 DOM 元素的代码,而攻击者在页面中插入一个新的标签并将其id
也设置为myElement
,那么后续的代码在获取myElement
时,可能会错误地获取到攻击者插入的这个新元素,而不是原本预期的那个元素。- 这种情况下,通过故意创建命名冲突的标签,攻击者可以改变网页中原有代码对 DOM 元素的引用路径,从而影响网页的正常逻辑。
- 利用特定标签的默认行为影响 DOM 解析:
- 一些特殊的 HTML 标签具有特定的默认行为和与浏览器交互的方式,这些行为可能会间接影响 DOM 的解析和引用。例如,
<script>
标签在加载外部脚本时,如果脚本中包含对全局变量的操作,而攻击者能够控制这个外部脚本的内容,那么就有可能通过这种方式来篡改全局变量的值或引用。- 同样,
<iframe>
标签可以加载外部网页,如果攻击者能够控制加载的外部网页内容,他们就可以通过在外部网页中构造特定的 DOM 结构和 JavaScript 代码,来影响包含<iframe>
的父页面的 DOM 环境。
三、利用浏览器解析差异和漏洞实现覆写
- 不同浏览器的解析差异导致的安全漏洞:
- 不同的浏览器在解析 HTML 和处理 DOM 时可能存在细微的差异和不一致性。攻击者可以利用这些差异来找到特定浏览器中的漏洞,从而实现 DOM clobbering。例如,某些浏览器在处理特殊字符、标签属性的解析顺序、命名冲突的解决方式等方面可能存在独特的行为,攻击者可以针对这些特点来构造特定的 HTML 结构和 JavaScript 交互方式,以达到覆写 DOM 元素的目的。
- 利用早期浏览器版本的已知漏洞:
- 较旧版本的浏览器可能存在一些已经被发现的安全漏洞,其中一些漏洞可能与 DOM 的解析和处理相关。攻击者可以针对这些已知漏洞,在特定的浏览器环境中实施 DOM clobbering 攻击。例如,某些早期版本的浏览器在处理特定类型的 HTML 标签嵌套或属性设置时,可能会出现错误的 DOM 构建或引用错误,攻击者可以利用这些漏洞来实现对关键 DOM 元素或变量的覆写。
案例分析:
案例一:
控制台打印结果:
通过上述结果分析可得:id和name中的值可以直接引用,引用的值即为标签的全部,但使用document可进行name引用,不可进行id引用。 DOM元素<img>拥有id属性=“x”,浏览器会自动在document对象上创建一个同名的属性document.x指向该DOM元素<img>,因此使用document.x可以直接抓取<img>标签,无需通过 getElementById 抓取<img>标签。
案例二:
我们可以看到输出值为空
而当我们新创建的<div>标签中插入一个<img>标签并将该<div>标签插入到<body>中后,再利用document.cookie函数输出网页的cookie时,输出的结果却由空值改变成<img>标签
造成这一现象的原因:
<img>标签拥有name属性=“cookie”,浏览器会自动在document对象上创建一个同名的属性document.cookie指向该DOM元素<img>
浏览器创建的同名name=cookie属性与已有的JavaScript内置属性名cookie冲突,会覆盖原有的JS代码的作用即执行document.cookie时不是获取当前网页的cookie值而是抓取<img>标签
这种行为虽然有时可以方便地访问元素,但也会引发一些潜在的问题,特别是在元素的属性名与JavaScript全局对象的属性名冲突时,可能会破坏正常的DOM操作或脚本运行。我们可以利用这种方法。