# DOM XSS {{#include ../../banners/hacktricks-training.md}} ## DOM Вразливості DOM вразливості виникають, коли дані з джерел, контрольованих зловмисником **sources** (як-от `location.search`, `document.referrer` або `document.cookie`), небезпечно передаються до **sinks**. Sinks — це функції або об'єкти (наприклад, `eval()`, `document.body.innerHTML`), які можуть виконувати або відображати шкідливий контент, якщо отримують зловмисні дані. - **Sources** — це вхідні дані, які можуть бути маніпульовані зловмисниками, включаючи URL-адреси, куки та веб-повідомлення. - **Sinks** — це потенційно небезпечні кінцеві точки, де зловмисні дані можуть призвести до негативних наслідків, таких як виконання скриптів. Ризик виникає, коли дані течуть з джерела до sink без належної валідації або очищення, що дозволяє атакам, таким як XSS. > [!TIP] > **Ви можете знайти більш актуальний список джерел і sinks на** [**https://github.com/wisec/domxsswiki/wiki**](https://github.com/wisec/domxsswiki/wiki) **Звичайні джерела:** ```javascript 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 ``` **Загальні місця витоку:** | [**Відкритий редирект**](dom-xss.md#open-redirect) | [**Впровадження Javascript**](dom-xss.md#javascript-injection) | [**Маніпуляція даними DOM**](dom-xss.md#dom-data-manipulation) | **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` | **\`\`**[**Маніпуляція локальним шляхом файлу**](dom-xss.md#local-file-path-manipulation) | `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 запитами**](dom-xss.md#ajax-request-manipulation) | `FileReader.readAsFile()` | `someDOMElement.backgroundImage` | `constructor()` | | `XMLHttpRequest.setRequestHeader()` | `FileReader.root.getFile()` | `someDOMElement.cssText` | `init()` | | `XMLHttpRequest.open()` | `FileReader.root.getFile()` | `someDOMElement.codebase` | `index()` | | `XMLHttpRequest.send()` | [**Маніпуляція посиланнями**](dom-xss.md#link-manipulation) | `someDOMElement.innerHTML` | `jQuery.parseHTML()` | | `jQuery.globalEval()` | `someDOMElement.href` | `someDOMElement.outerHTML` | `$.parseHTML()` | | `$.globalEval()` | `someDOMElement.src` | `someDOMElement.insertAdjacentHTML` | [**Впровадження JSON на стороні клієнта**](dom-xss.md#client-side-sql-injection) | | **\`\`**[**Маніпуляція HTML5-сховищем**](dom-xss.md#html-5-storage-manipulation) | `someDOMElement.action` | `someDOMElement.onevent` | `JSON.parse()` | | `sessionStorage.setItem()` | [**Впровадження XPath**](dom-xss.md#xpath-injection) | `document.write()` | `jQuery.parseJSON()` | | `localStorage.setItem()` | `document.evaluate()` | `document.writeln()` | `$.parseJSON()` | | **``**[**`Відмова в обслуговуванні`**](dom-xss.md#denial-of-service)**``** | `someDOMElement.evaluate()` | `document.title` | **\`\`**[**Маніпуляція куками**](dom-xss.md#cookie-manipulation) | | `requestFileSystem()` | **\`\`**[**Маніпуляція доменом документа**](dom-xss.md#document-domain-manipulation) | `document.implementation.createHTMLDocument()` | `document.cookie` | | `RegExp()` | `document.domain` | `history.pushState()` | [**Отруєння URL WebSocket**](dom-xss.md#websocket-url-poisoning) | | [**Впровадження SQl на стороні клієнта**](dom-xss.md#client-side-sql-injection) | [**Маніпуляція веб-повідомленнями**](dom-xss.md#web-message-manipulation) | `history.replaceState()` | `WebSocket` | | `executeSql()` | `postMessage()` | \`\` | \`\` | Синк **`innerHTML`** не приймає `script` елементи в жодному сучасному браузері, і події `svg onload` не спрацюють. Це означає, що вам потрібно буде використовувати альтернативні елементи, такі як `img` або `iframe`. Цей вид XSS, ймовірно, є **найскладнішим для виявлення**, оскільки вам потрібно заглянути в код JS, перевірити, чи **використовується** будь-який об'єкт, значення якого ви контролюєте, і в такому випадку перевірити, чи є **будь-який спосіб зловживання** ним для виконання довільного JS. ## Інструменти для їх виявлення - [https://github.com/mozilla/eslint-plugin-no-unsanitized](https://github.com/mozilla/eslint-plugin-no-unsanitized) - Розширення браузера для перевірки всіх даних, які досягають потенційного місця витоку: [https://github.com/kevin-mizu/domloggerpp](https://github.com/kevin-mizu/domloggerpp) ## Приклади ### Відкритий редирект З: [https://portswigger.net/web-security/dom-based/open-redirection](https://portswigger.net/web-security/dom-based/open-redirection) **Вразливості відкритого редиректу в DOM** виникають, коли скрипт записує дані, які може контролювати зловмисник, у місце витоку, здатне ініціювати навігацію між доменами. Важливо розуміти, що виконання довільного коду, такого як **`javascript:alert(1)`**, можливе, якщо ви контролюєте початок URL, де відбувається редирект. Місця витоку: ```javascript 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](https://portswigger.net/web-security/dom-based/cookie-manipulation) Вразливості маніпуляції з куками на основі DOM виникають, коли скрипт включає дані, які можуть контролюватися зловмисником, у значення куки. Ця вразливість може призвести до несподіваної поведінки веб-сторінки, якщо кука використовується на сайті. Крім того, її можна експлуатувати для проведення атаки фіксації сесії, якщо кука залучена до відстеження сесій користувачів. Основний "синк", пов'язаний з цією вразливістю, це: Синки: ```javascript document.cookie ``` ### JavaScript Injection From: [https://portswigger.net/web-security/dom-based/javascript-injection](https://portswigger.net/web-security/dom-based/javascript-injection) Вразливості DOM-орієнтованої ін'єкції JavaScript виникають, коли скрипт виконує дані, які можуть контролюватися зловмисником, як код JavaScript. Sinks: ```javascript eval() Function() constructor setTimeout() setInterval() setImmediate() execCommand() execScript() msSetImmediate() range.createContextualFragment() crypto.generateCRMFRequest() ``` ### Маніпуляція з документом-доменом From: [https://portswigger.net/web-security/dom-based/document-domain-manipulation](https://portswigger.net/web-security/dom-based/document-domain-manipulation) **Вразливості маніпуляції з документом-доменом** виникають, коли скрипт встановлює властивість `document.domain`, використовуючи дані, якими може керувати зловмисник. Властивість `document.domain` відіграє **ключову роль** у **забезпеченні** **політики однакового походження** браузерами. Коли дві сторінки з різних походжень встановлюють свій `document.domain` на **однакове значення**, вони можуть взаємодіяти без обмежень. Хоча браузери накладають певні **обмеження** на значення, які можна призначити `document.domain`, заважаючи призначенню абсолютно несумісних значень фактичному походженню сторінки, існують винятки. Зазвичай браузери дозволяють використання **дочірніх** або **батьківських доменів**. Sinks: ```javascript document.domain ``` ### WebSocket-URL poisoning From: [https://portswigger.net/web-security/dom-based/websocket-url-poisoning](https://portswigger.net/web-security/dom-based/websocket-url-poisoning) **WebSocket-URL poisoning** відбувається, коли скрипт використовує **керовані дані як цільовий URL** для з'єднання WebSocket. Sinks: Конструктор `WebSocket` може призвести до вразливостей WebSocket-URL poisoning. ### Link manipulation From: [https://portswigger.net/web-security/dom-based/link-manipulation](https://portswigger.net/web-security/dom-based/link-manipulation) **Вразливості маніпуляції з посиланнями на основі DOM** виникають, коли скрипт записує **дані, контрольовані атакуючим, до цільового навігаційного елемента** на поточній сторінці, такого як клікабельне посилання або URL для відправки форми. Sinks: ```javascript someDOMElement.href someDOMElement.src someDOMElement.action ``` ### Маніпуляція запитом Ajax З: [https://portswigger.net/web-security/dom-based/ajax-request-header-manipulation](https://portswigger.net/web-security/dom-based/ajax-request-header-manipulation) **Вразливості маніпуляції запитом Ajax** виникають, коли скрипт записує **дані, контрольовані атакуючими, у запит Ajax**, який надсилається за допомогою об'єкта `XmlHttpRequest`. Синьки: ```javascript XMLHttpRequest.setRequestHeader() XMLHttpRequest.open() XMLHttpRequest.send() jQuery.globalEval() $.globalEval() ``` ### Локальна маніпуляція шляхом до файлу З: [https://portswigger.net/web-security/dom-based/local-file-path-manipulation](https://portswigger.net/web-security/dom-based/local-file-path-manipulation) **Вразливості локальної маніпуляції шляхом до файлу** виникають, коли скрипт передає **дані, контрольовані атакуючим, до API обробки файлів** як параметр `filename`. Цю вразливість може експлуатувати атакуючий, щоб створити URL, який, якщо його відвідає інший користувач, може призвести до **відкриття або запису випадкового локального файлу в браузері користувача**. Sinks: ```javascript FileReader.readAsArrayBuffer() FileReader.readAsBinaryString() FileReader.readAsDataURL() FileReader.readAsText() FileReader.readAsFile() FileReader.root.getFile() FileReader.root.getFile() ``` ### Client-Side SQl injection From: [https://portswigger.net/web-security/dom-based/client-side-sql-injection](https://portswigger.net/web-security/dom-based/client-side-sql-injection) **Вразливості SQL-ін'єкцій на стороні клієнта** виникають, коли скрипт включає **дані, контрольовані атакуючим, у SQL-запит на стороні клієнта ненадійним способом**. Sinks: ```javascript executeSql() ``` ### HTML5-storage manipulation From: [https://portswigger.net/web-security/dom-based/html5-storage-manipulation](https://portswigger.net/web-security/dom-based/html5-storage-manipulation) **Вразливості маніпуляцій з HTML5-сховищем** виникають, коли скрипт **зберігає дані, контрольовані атакуючим, у HTML5-сховищі веб-браузера** (`localStorage` або `sessionStorage`). Хоча ця дія сама по собі не є вразливістю безпеки, вона стає проблематичною, якщо програма потім **читає збережені дані та обробляє їх ненадійно**. Це може дозволити атакуючому використовувати механізм сховища для проведення інших атак на основі DOM, таких як міжсайтове скриптування та ін'єкція JavaScript. Sinks: ```javascript sessionStorage.setItem() localStorage.setItem() ``` ### XPath ін'єкція From: [https://portswigger.net/web-security/dom-based/client-side-xpath-injection](https://portswigger.net/web-security/dom-based/client-side-xpath-injection) **Вразливості DOM-ін'єкції XPath** виникають, коли скрипт включає **дані, контрольовані атакуючими, в запит XPath**. Sinks: ```javascript document.evaluate() someDOMElement.evaluate() ``` ### Впровадження JSON на стороні клієнта З: [https://portswigger.net/web-security/dom-based/client-side-json-injection](https://portswigger.net/web-security/dom-based/client-side-json-injection) **Вразливості впровадження JSON на основі DOM** виникають, коли скрипт включає **дані, контрольовані зловмисником, у рядок, який розбирається як структура даних JSON, а потім обробляється додатком**. Синки: ```javascript JSON.parse() jQuery.parseJSON() $.parseJSON() ``` ### Веб-маніпуляція повідомленнями From: [https://portswigger.net/web-security/dom-based/web-message-manipulation](https://portswigger.net/web-security/dom-based/web-message-manipulation) **Вразливості веб-повідомлень** виникають, коли скрипт надсилає **дані, контрольовані зловмисником, як веб-повідомлення до іншого документа** в браузері. **Приклад** вразливої маніпуляції веб-повідомленнями можна знайти в [Web Security Academy PortSwigger](https://portswigger.net/web-security/dom-based/controlling-the-web-message-source). Sinks: Метод `postMessage()` для надсилання веб-повідомлень може призвести до вразливостей, якщо обробник подій для отримання повідомлень обробляє вхідні дані ненадійним способом. ### Маніпуляція даними DOM From: [https://portswigger.net/web-security/dom-based/dom-data-manipulation](https://portswigger.net/web-security/dom-based/dom-data-manipulation) **Вразливості маніпуляції даними DOM** виникають, коли скрипт записує **дані, контрольовані зловмисником, у поле в DOM**, яке використовується в видимому інтерфейсі або логіці на стороні клієнта. Цю вразливість може експлуатувати зловмисник, щоб створити URL, який, якщо його відвідає інший користувач, може змінити вигляд або поведінку інтерфейсу на стороні клієнта. Sinks: ```javascript 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 From: [https://portswigger.net/web-security/dom-based/denial-of-service](https://portswigger.net/web-security/dom-based/denial-of-service) **Уразливості відмови в обслуговуванні на основі DOM** виникають, коли скрипт передає **дані, контрольовані зловмисником, небезпечно до проблемного API платформи**. Це включає API, які, коли їх викликають, можуть призвести до споживання **надмірної кількості процесорного часу або дискового простору** на комп'ютері користувача. Такі уразливості можуть мати значні побічні ефекти, такі як обмеження функціональності веб-сайту браузером шляхом відхилення спроб зберегти дані в `localStorage` або завершення зайнятих скриптів. Sinks: ```javascript requestFileSystem() RegExp() ``` ## Dom Clobbering {{#ref}} dom-clobbering.md {{#endref}} {{#include ../../banners/hacktricks-training.md}}