基于DOM的漏洞
翻译
原文:https://portswigger.net/web-security/dom-based
- name: 翻译
desc: 原文:https://portswigger.net/web-security/dom-based
bgColor: '#F0DFB1'
textColor: 'green'
2
3
4
# 0基于DOM的漏洞
在本节中,我们将描述什么是 DOM,解释 DOM 数据的不安全处理是如何引入漏洞的,并提供有关如何防范网站上基于 DOM 的漏洞的一些建议。
实验室
如果您已经熟悉基于 DOM 的漏洞背后的基本概念,并且只想在一些实际的、易受攻击的目标上练习和利用它们,那么您可以从下面的链接访问本主题中的所有实验室。
# 1什么是DOM?
文档对象模型(DOM)是 Web 浏览器对网页元素的分层表示形式。网站可以使用 JavaScript 来操作 DOM 节点和对象,以及它们的属性。DOM 操作本身并不是什么问题。事实上,它是现代网站工作方式的一个组成部分,是不可或缺的。但是,当使用 JavaScript 以不安全的方式处理数据时,可能会引发各种攻击。当网站包含 JavaScript 时,就会出现基于 DOM 的漏洞,该 JavaScript 接收攻击者可控的值(称为“源”)并将其传递到危险的函数中(称为“接收器”)。
# 2污点流漏洞
许多基于 DOM 的漏洞,都可以追溯到 “客户端代码 以何种方式 操纵攻击者可控数据” 的问题。
# 2.1什么是污点流?
若想利用或缓解这些漏洞,首先要熟悉污点流中的源和接收器,掌握其中的基础知识是非常重要的。
# 2.1.1源
源是一个 JavaScript 属性,它接收可能受攻击者控制的数据。源的一个示例是location.search
属性,由于它会从 URL 查询字符串中读取输入,所以这对于攻击者来说相对容易控制。最终,攻击者可以控制的任何属性 都是潜在的来源。这包括引用 URL(由document.referrer
接收的字符串)、用户的 cookie(由document.cookie
接收的字符串)和 Web 消息。
# 2.1.2接收器
接收器是一个具有潜在危险的 JavaScript 函数或 DOM 对象,如果将攻击者控制的数据传递给它,可能会导致不良影响。例如,eval()
函数是一个接收器,因为它会将给定参数作为 JavaScript 处理。HTML 接收器的一个示例是document.body.innerHTML
,因为它可能允许攻击者注入恶意 HTML 并执行任意 JavaScript。
从根本上说,当网站将数据从源 传递到 接收器,然后在客户端会话的上下文中 以不安全的方式处理数据时,就会出现基于 DOM 的漏洞。
最常见的源是 URL,通常使用location
对象即可访问 URL。攻击者可以构造一个链接,然后将受害者转到易受攻击的页面,该页面的查询字符串和 URL 片段部分中具有攻击负载。请考虑以下代码:
goto = location.hash.slice(1)
if (goto.startsWith('https:')) {
location = goto;
}
2
3
4
以上代码容易受到基于DOM的开放重定向 (opens new window)的攻击,因为location.hash
源是以不安全的方式处理的。如果 URL 中包含一个以https
开头的 hash 片段,则此代码将提取location.hash
属性的值,并将其设置为window
对象的location
属性值。攻击者可以通过构造以下 URL 来利用此漏洞:
https:/example#https://www.evil-user.net
当受害者访问此 URL 时,JavaScript 会将location
属性的值设置为https://www.evil-user.net
,这会自动将受害者重定向到恶意站点。举个例子,这种行为很容易被利用来构建 网络钓鱼 攻击。
# 2.2一些常见的源
以下是适用于 利用各种污点流漏洞 的典型来源:
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
2
3
4
5
6
7
8
9
10
11
12
13
14
以下类型的数据也可用作 利用污点流漏洞 的源:
# 2.3哪些接收器会导致基于 DOM 的漏洞?
以下列表提供了常见的基于 DOM 的漏洞的快速概述,以及可能导致每个漏洞的接收器示例。有关相应接收器的更全面列表,请单击下面的链接,阅读特定的漏洞页面。
基于DOM的漏洞 | 接收器示例 |
---|---|
DOM型XSS (opens new window)LABS | document.write() |
开放重定向 (opens new window)LABS | window.location |
Cookie操纵 (opens new window)LABS | document.cookie |
JavaScript注入 (opens new window) | eval() |
文档域操纵 (opens new window) | document.domain |
WebSocket-URL投毒 (opens new window) | WebSocket() |
链接操纵 (opens new window) | element.src |
Web消息操纵 (opens new window) | postMessage() |
Ajax请求头操纵 (opens new window) | setRequestHeader() |
本地文件路径操纵 (opens new window) | FileReader.readAsText() |
客户端SQL注入 (opens new window) | ExecuteSql() |
HTML5存储操纵 (opens new window) | sessionStorage.setItem() |
客户端XPath注入 (opens new window) | document.evaluate() |
客户端JSON注入 (opens new window) | JSON.parse() |
DOM数据操纵 (opens new window) | element.setAttribute() |
拒绝服务 (opens new window) | RegExp() |
# 2.4如何防范基于DOM的污点流漏洞
没有任何单一的措施 可以完全消除基于 DOM 的攻击威胁。然而,一般来说,避免基于 DOM 的漏洞的最有效方法是——任何来自不受信任源的数据,以及任何传输到接收器的值,都不允许动态地变更。
(((译者加:简单来讲,就是不允许动态接收用户输入、不要根据用户输入来动态变更 DOM 文档中的元素)))
如果应用程序需要这种功能,意味着此行为是不可避免的,那么必须在客户端代码中实现防御。
- 在许多情况下,可以在白名单的基础上验证相关数据,仅允许已知安全的内容。
- 在其他情况下,有必要对数据进行清理或编码,这需要分析插入数据的上下文,并按适当的顺序实施 JavaScript 转义、HTML 编码和 URL 编码的组合。这可能是一项复杂的任务。
你可以针对某个漏洞 采取特定的防范措施,请参阅上表中的链接,阅读相应的漏洞页面。
# 3DOM clobbering
DOM clobbering 是一种高级技术,你可以将 HTML 注入到网页中来操作 DOM,并最终改变网站上 JavaScript 的行为运作方式。最常见的 DOM clobbering 攻击形式会使用锚元素来覆盖全局变量,然后应用程序将会以不安全的方式 使用该全局变量,例如生成动态 URL 脚本。