写在前面的话
本文将给大家介绍一种名为DOM Clobbering的技术,并为经验丰富的安全研究人员和开发人员提供针对DOM Clobbering漏洞的安全开发指南。
关于DOM Clobbering
DOM Clobbering是一种无JavaScript注入攻击,威胁行为者可以通过在网页HTML代码中插入一段非 <script>标签代码,并利用命名属性访问方法将其转换成可执行代码,从而混淆Web应用程序客户端的JavaScript代码。
DOM Clobbering漏洞来源于JavaScript变量和命名HTML标签之间的命名冲突,例如带有id或name属性的标签等等。
DOM中的命名属性
JavaScript脚本代码处理网页内容的方法之一是通过文档对象模型(DOM),即呈现网页的树状结构表示。一般来说,DOM树元素可以在JavaScript中通过文档对象的对象选择器方法访问,比如说通过document.getElementById(x)来定位id为x的 元素。
然而,这并非唯一的方法,因为我们也可以通过document和全局window对象的属性来实现相同的效果,例如document.x或window.x,即我们所说的“命名属性访问”。
相应的,Web浏览器会基于元素命名属性自动地将HTML元素映射到JavaScript对象,例如HTML标签属性id和name等。
需要注意的是,所有的document属性都可以被DOM Clobbering覆盖,受DOM Clobbering影响的window属性如下图所示:
漏洞代码样例
当一个未定义变量和一个HTML标签拥有相同的名称时,浏览器将变量的内容替换为映射标签类型的DOM对象。
示例代码一:
1. var s = document.createElement('script'); 2. let config = window.globalConfig || {href: 'script.js'}; 3. s.src = config.href; 4. document.body.appendChild(s);
上面的代码段存在DOM Clobbering漏洞,该代码段加载了一个脚本,这个脚本的URL存储在一个全局配置对象中,例如window.globalConfig。具体来说,该代码首先会创建一个script标签(第1行),然后检索全局配置对象并将其存储至一个本地变量config中(第2行)。如果配置对象不存在,它将使用一个最小化配置,例如{href: script.js'}(第2行)。接下来,程序会将新创建的脚本标签的src属性设置为配置对象的href属性(第3行),并将新脚本添加到DOM树中,从而实现脚本代码的执行(第4行)。
漏洞就出在第二行的赋值操作,因为威胁行为者可以控制window.globalConfig的值,并通过注入一个包含id="globalConfig"的HTML标签来选择脚本src属性的值,比如说:
<a href="https://www.freebuf.com/articles/web/malicious.js">
在解析这种类型的标签代码时,浏览器往往会根据命名属性访问的要求,将锚点标签元素映射到window.globalConfig属性。升级到任意代码执行则发生在上述的第三行代码处,该行代码会读取window.globalConfig对象的href属性,而该属性不再包含具有全局配置的对象,反而包含了威胁行为者控制的锚点标签,其href属性值为malicious.js。
需要注意的是,威胁行为者可以通过其他的方法来滥用“命名属性访问”这种方法,即不通过HTML节点覆盖变量,而是覆盖浏览器API。比如说,如果威胁行为者在DOM中插入一个id=getElementbyId的标签,那么document.getElementbyId这个API将不再引用内置的API来查找DOM树中的元素,而是在DOM树中反射id为getElementbyId的DOM元素。这种行为就是由所谓的“命名属性可见性算法”所造成的。
示例代码二:
1. document.conf = {}; 2. const queryParams = new URLSearchParams(window.location.search); 3. if(isTrustedOrigin(queryParams.get('next'))){ 4. document.conf.src = queryParams.get('next'); 5. } 6. // [...] 7. let next = document.conf.src || 'https://benign1.com/index.html'; 8. window.location.href = next; 9. // [...] 10. function isTrustedOrigin(url){ 11. let targetOrigin = new URL(url).origin; 12. let trustedOrigins= [ 13. new URL('https://benign1.com').origin, 14. new URL('https://benign2.com').origin 15. ]; 16. if(trustedOrigins.indexOf(targetOrigin) !== -1) return true; 17. return false; 18. }
上面的代码段可以读取查询参数的值,如果它属于受信任域,它会将其全局存储在document.conf.src中(第1至4行)。然后,它会将页面重定向到document.conf.src或默认值(第6行)。
该脚本存在DOM Clobbering漏洞,是因为它忽略了对document的赋值是可以被DOM Clobbering覆盖掉的。比如说,如果威胁行为者注入了下列代码:
<img name="conf" src="javascript:alert(1)">
那么document.conf将会指向一个img标签,因此document.conf.src就变成了一个威胁行为者控制的JavaScript Payload,当其被分配到顶部窗口位置时,将导致XSS(第8行)。
DOM Clobbering的代码模式
常见的DOM Clobbering漏洞代码模式如下图所示:
最常见的错误就是模式A和模式E,在这两种模式中,开发人员通过Windowobject引用了未定义的变量,然后在敏感指令中使用了结果。最不常见但也更复杂的错误则是模式F、G和H,其中漏洞源于跨两个不同脚本标签的指令位置。
其他常见的错误是模式B和C,在这里,开发人员将自定义的和本地document以及window属性视为受信任的值,然后将其用于了敏感操作中。
安全编码模式指南
显式变量声明
如上图所示,导致DOM Clobbering的一个关键因素是在未定义主要变量、预期变量或属性时,使用了||运算符并依赖于特定的默认值,那么在这些变量未定义时,开发人员可以使用var声明并通过默认值来初始化这些变量,并通过命名属性可见性算法来防止命名属性覆盖它们,这种方法可以解决上述的模式A、D、E、F和H。
严格的类型检查
导致DOM Clobbering的另一个常见错误时将DOM属性(如document和window属性)视为安全和可信任的值(例如模式B、C和G)。相反,开发人员应该将信任边界扩展到这些属性,在安全敏感指令中使用它们之前验证它们的类型,比如说通过利用instanceof和typeof运算符进行类型验证。
不要用document处理全局变量
document的属性总是可以被DOM Clobbering覆盖的,甚至在它们被分配了值之后就立即被覆盖,比如说模式C。因此,开发人员应该避免使用document来存储和检索全局值。相反,我们可以在全局上下文中用const或var声明变量,或者使用globalThis对象来实现相同的目的。
命名空间隔离
另一种解决方案是将JavaScript代码定义的变量的命名空间与用户生成标签中的命名属性隔离开。比如说,源代码版本控制应用程序的markdown转HTML工具通常就会在用户生成标签的id和name属性值前面加上特定的字符串,那么根据这种方式,我们就可以通过MutationObserver API监视DOM树中的运行时变化,并在将所有动态插入的标签添加到DOM树之前为其加上前缀,从而修复上述所有易受攻击的模式。
安全防御建议
1、采用安全的编码模式;
2、HTML代码清洗;
3、采用内容安全策略(CSP);
4、固定对象属性(通过Object.freeze()方法);
5、禁用DOM Clobbering;
参考资料
https://html.spec.whatwg.org/multipage/window-object.html#named-access-on-the-window-object
https://www.w3.org/TR/WD-DOM/introduction.html
https://www.w3.org/TR/selectors-4/
https://developer.mozilla.org/en-US/docs/Web/API/Document
https://html.spec.whatwg.org/multipage/window-object.html#named-access-on-the-window-object
https://html.spec.whatwg.org/multipage/dom.html#dom-tree-accessors
https://portswigger.net/research/dom-clobbering-strikes-back
https://fastmail.blog/advanced/sanitising-html-the-dom-clobbering-issue/
https://link.springer.com/chapter/10.1007/978-3-319-66399-9_7
https://webidl.spec.whatwg.org/#legacy-platform-object-abstract-ops
参考链接
4A评测 - 免责申明
本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。
不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。
本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。
如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!
程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。
侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)