20 KiB
Raw Blame History

DOM XSS

{{#include ../../banners/hacktricks-training.md}}

DOM 漏洞

DOM 漏洞发生在来自攻击者控制的 sources(如 location.searchdocument.referrerdocument.cookie)的数据不安全地传输到 sinks 时。Sinks 是可以执行或渲染有害内容的函数或对象(例如 eval()document.body.innerHTML),如果给定恶意数据。

  • Sources 是可以被攻击者操控的输入,包括 URL、cookies 和网页消息。
  • Sinks 是潜在危险的端点,恶意数据可能导致不良后果,例如脚本执行。

风险在于数据从源流向汇时没有适当的验证或清理,从而使攻击如 XSS 成为可能。

Note

您可以在 https://github.com/wisec/domxsswiki/wiki 找到更更新的 sources 和 sinks 列表

常见 sources

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

常见的接收点:

开放重定向 Javascript 注入 DOM 数据操作 jQuery
location eval() scriptElement.src add()
location.host Function() constructor scriptElement.text after()
location.hostname setTimeout() scriptElement.textContent append()
location.href setInterval() scriptElement.innerText animate()
location.pathname setImmediate() someDOMElement.setAttribute() insertAfter()
location.search execCommand() someDOMElement.search insertBefore()
location.protocol execScript() someDOMElement.text before()
location.assign() msSetImmediate() someDOMElement.textContent html()
location.replace() range.createContextualFragment() someDOMElement.innerText prepend()
open() crypto.generateCRMFRequest() someDOMElement.outerText replaceAll()
domElem.srcdoc ``本地文件路径操作 someDOMElement.value replaceWith()
XMLHttpRequest.open() FileReader.readAsArrayBuffer() someDOMElement.name wrap()
XMLHttpRequest.send() FileReader.readAsBinaryString() someDOMElement.target wrapInner()
jQuery.ajax() FileReader.readAsDataURL() someDOMElement.method wrapAll()
$.ajax() FileReader.readAsText() someDOMElement.type has()
``Ajax 请求操作 FileReader.readAsFile() someDOMElement.backgroundImage constructor()
XMLHttpRequest.setRequestHeader() FileReader.root.getFile() someDOMElement.cssText init()
XMLHttpRequest.open() FileReader.root.getFile() someDOMElement.codebase index()
XMLHttpRequest.send() 链接操作 someDOMElement.innerHTML jQuery.parseHTML()
jQuery.globalEval() someDOMElement.href someDOMElement.outerHTML $.parseHTML()
$.globalEval() someDOMElement.src someDOMElement.insertAdjacentHTML 客户端 JSON 注入
``HTML5 存储操作 someDOMElement.action someDOMElement.onevent JSON.parse()
sessionStorage.setItem() XPath 注入 document.write() jQuery.parseJSON()
localStorage.setItem() document.evaluate() document.writeln() $.parseJSON()
**[**拒绝服务**](dom-xss.md#denial-of-service)** someDOMElement.evaluate() document.title ``Cookie 操作
requestFileSystem() ``文档域操作 document.implementation.createHTMLDocument() document.cookie
RegExp() document.domain history.pushState() WebSocket-URL 中毒
客户端 SQL 注入 Web 消息操作 history.replaceState() WebSocket
executeSql() postMessage() `` ``

innerHTML 接收点在任何现代浏览器中都不接受 script 元素,也不会触发 svg onload 事件。这意味着您需要使用替代元素,如 imgiframe

这种类型的 XSS 可能是 最难发现的,因为您需要查看 JS 代码,看看它是否 使用 任何您 控制 的对象,并在这种情况下,查看是否有 任何方法可以滥用 它以执行任意 JS。

查找工具

示例

开放重定向

来自:https://portswigger.net/web-security/dom-based/open-redirection

DOM 中的开放重定向漏洞 发生在脚本将攻击者可以控制的数据写入能够跨域发起导航的接收点时。

理解执行任意代码(例如 javascript:alert(1))是可能的,如果您控制重定向发生的 URL 开头,这是至关重要的。

接收点:

location
location.host
location.hostname
location.href
location.pathname
location.search
location.protocol
location.assign()
location.replace()
open()
domElem.srcdoc
XMLHttpRequest.open()
XMLHttpRequest.send()
jQuery.ajax()
$.ajax()

来自: https://portswigger.net/web-security/dom-based/cookie-manipulation

基于DOM的cookie操控漏洞发生在脚本将攻击者可以控制的数据纳入cookie的值时。如果在网站内使用该cookie这个漏洞可能导致网页出现意外行为。此外如果cookie涉及用户会话跟踪它可以被利用来进行会话固定攻击。与此漏洞相关的主要接收点是

Sinks:

document.cookie

JavaScript 注入

来自: https://portswigger.net/web-security/dom-based/javascript-injection

基于 DOM 的 JavaScript 注入漏洞是在脚本将可以被攻击者控制的数据作为 JavaScript 代码运行时产生的。

Sinks:

eval()
Function() constructor
setTimeout()
setInterval()
setImmediate()
execCommand()
execScript()
msSetImmediate()
range.createContextualFragment()
crypto.generateCRMFRequest()

Document-domain manipulation

From: https://portswigger.net/web-security/dom-based/document-domain-manipulation

文档域操控漏洞发生在脚本使用攻击者可以控制的数据设置document.domain属性时。

document.domain属性在浏览器的同源策略执行中发挥着关键作用。当来自不同源的两个页面将其document.domain设置为相同的值时,它们可以不受限制地相互交互。尽管浏览器对可分配给document.domain的值施加了某些限制,防止将完全不相关的值分配给实际页面源,但仍然存在例外。通常,浏览器允许使用子域父域

Sinks:

document.domain

WebSocket-URL 中毒

来自: https://portswigger.net/web-security/dom-based/websocket-url-poisoning

WebSocket-URL 中毒 发生在脚本将 可控数据作为 WebSocket 连接的目标 URL 使用时。

Sinks:

WebSocket 构造函数可能导致 WebSocket-URL 中毒漏洞。

链接操控

来自: https://portswigger.net/web-security/dom-based/link-manipulation

基于 DOM 的链接操控漏洞 出现于脚本将 攻击者可控的数据写入当前页面的导航目标,例如可点击的链接或表单的提交 URL。

Sinks:

someDOMElement.href
someDOMElement.src
someDOMElement.action

Ajax 请求操控

来自: https://portswigger.net/web-security/dom-based/ajax-request-header-manipulation

Ajax 请求操控漏洞 出现于脚本将 攻击者可控的数据写入使用 XmlHttpRequest 对象发出的 Ajax 请求 时。

接收点:

XMLHttpRequest.setRequestHeader()
XMLHttpRequest.open()
XMLHttpRequest.send()
jQuery.globalEval()
$.globalEval()

本地文件路径操控

来自: https://portswigger.net/web-security/dom-based/local-file-path-manipulation

本地文件路径操控漏洞 出现于脚本将 攻击者可控的数据传递给文件处理API 作为 filename 参数时。攻击者可以利用此漏洞构造一个URL如果另一个用户访问该URL可能导致 用户的浏览器打开或写入任意本地文件

Sinks:

FileReader.readAsArrayBuffer()
FileReader.readAsBinaryString()
FileReader.readAsDataURL()
FileReader.readAsText()
FileReader.readAsFile()
FileReader.root.getFile()
FileReader.root.getFile()

客户端 SQL 注入

来自: https://portswigger.net/web-security/dom-based/client-side-sql-injection

客户端 SQL 注入漏洞 发生在脚本以 不安全的方式将攻击者可控的数据纳入客户端 SQL 查询 时。

Sinks:

executeSql()

HTML5-storage manipulation

From: https://portswigger.net/web-security/dom-based/html5-storage-manipulation

HTML5-storage manipulation vulnerabilities 出现于脚本 在网页浏览器的 HTML5 存储中存储攻击者可控的数据 (localStoragesessionStorage)。虽然此操作本身并不是安全漏洞,但如果应用程序随后 读取存储的数据并不安全地处理它,则会变得有问题。这可能允许攻击者利用存储机制进行其他基于 DOM 的攻击,例如跨站脚本和 JavaScript 注入。

Sinks:

sessionStorage.setItem()
localStorage.setItem()

XPath 注入

来自: https://portswigger.net/web-security/dom-based/client-side-xpath-injection

基于 DOM 的 XPath 注入漏洞 发生在脚本将 攻击者可控的数据纳入 XPath 查询 时。

Sinks:

document.evaluate()
someDOMElement.evaluate()

客户端 JSON 注入

来自: https://portswigger.net/web-security/dom-based/client-side-json-injection

基于 DOM 的 JSON 注入漏洞 发生在脚本将 攻击者可控的数据纳入一个被解析为 JSON 数据结构的字符串中,然后由应用程序处理

Sinks:

JSON.parse()
jQuery.parseJSON()
$.parseJSON()

Web-message manipulation

来自: https://portswigger.net/web-security/dom-based/web-message-manipulation

Web-message 漏洞 出现于脚本将 攻击者可控的数据作为网络消息发送到浏览器内的另一个文档。一个 示例 的易受攻击的 Web-message 操作可以在 PortSwigger's Web Security Academy 找到。

Sinks:

postMessage() 方法用于发送网络消息,如果接收消息的事件监听器以不安全的方式处理传入数据,可能会导致漏洞。

DOM-data manipulation

来自: https://portswigger.net/web-security/dom-based/dom-data-manipulation

DOM-data 操作漏洞 出现于脚本将 攻击者可控的数据写入 DOM 中的一个字段,该字段在可见的 UI 或客户端逻辑中被使用。攻击者可以利用此漏洞构造一个 URL如果其他用户访问该 URL可能会改变客户端 UI 的外观或行为。

Sinks:

scriptElement.src
scriptElement.text
scriptElement.textContent
scriptElement.innerText
someDOMElement.setAttribute()
someDOMElement.search
someDOMElement.text
someDOMElement.textContent
someDOMElement.innerText
someDOMElement.outerText
someDOMElement.value
someDOMElement.name
someDOMElement.target
someDOMElement.method
someDOMElement.type
someDOMElement.backgroundImage
someDOMElement.cssText
someDOMElement.codebase
document.title
document.implementation.createHTMLDocument()
history.pushState()
history.replaceState()

拒绝服务

来自: https://portswigger.net/web-security/dom-based/denial-of-service

基于DOM的拒绝服务漏洞发生在脚本将攻击者可控的数据不安全地传递给有问题的平台API时。这包括在调用时可能导致用户计算机消耗过多的CPU或磁盘空间的API。这类漏洞可能会产生显著的副作用例如浏览器通过拒绝尝试在localStorage中存储数据或终止繁忙的脚本来限制网站的功能。

Sinks:

requestFileSystem()
RegExp()

DOM覆盖

{{#ref}} dom-clobbering.md {{#endref}}

{{#include ../../banners/hacktricks-training.md}}