mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
301 lines
26 KiB
Markdown
301 lines
26 KiB
Markdown
# DOM XSS
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
## DOM Вразливості
|
||
|
||
DOM вразливості виникають, коли дані з джерел, контрольованих зловмисником (**sources**, такі як `location.search`, `document.referrer` або `document.cookie`), небезпечно передаються до **синків**. Синки - це функції або об'єкти (наприклад, `eval()`, `document.body.innerHTML`), які можуть виконувати або відображати шкідливий контент, якщо отримують зловмисні дані.
|
||
|
||
- **Джерела** - це вхідні дані, які можуть бути маніпульовані зловмисниками, включаючи URL-адреси, куки та веб-повідомлення.
|
||
- **Синки** - це потенційно небезпечні кінцеві точки, де зловмисні дані можуть призвести до негативних наслідків, таких як виконання скриптів.
|
||
|
||
Ризик виникає, коли дані течуть від джерела до синка без належної валідації або очищення, що дозволяє атакам, таким як XSS.
|
||
|
||
> [!NOTE]
|
||
> **Ви можете знайти більш актуальний список джерел і синків у** [**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, виникають, коли скрипт включає дані, які можуть контролюватися зловмисником, у значення куки. Ця вразливість може призвести до несподіваної поведінки веб-сторінки, якщо кука використовується на сайті. Крім того, її можна експлуатувати для проведення атаки фіксації сесії, якщо кука залучена до відстеження сесій користувачів. Основний sink, пов'язаний з цією вразливістю, це:
|
||
|
||
Sinks:
|
||
```javascript
|
||
document.cookie
|
||
```
|
||
### Впровадження JavaScript
|
||
|
||
З: [https://portswigger.net/web-security/dom-based/javascript-injection](https://portswigger.net/web-security/dom-based/javascript-injection)
|
||
|
||
Вразливості впровадження JavaScript на основі DOM виникають, коли скрипт виконує дані, які можуть контролюватися зловмисником, як код JavaScript.
|
||
|
||
Синьки:
|
||
```javascript
|
||
eval()
|
||
Function() constructor
|
||
setTimeout()
|
||
setInterval()
|
||
setImmediate()
|
||
execCommand()
|
||
execScript()
|
||
msSetImmediate()
|
||
range.createContextualFragment()
|
||
crypto.generateCRMFRequest()
|
||
```
|
||
### Маніпуляція документом-доменом
|
||
|
||
З: [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`, заважаючи присвоєнню абсолютно несумісних значень фактичному походженню сторінки, існують винятки. Зазвичай браузери дозволяють використання **дочірніх** або **батьківських доменів**.
|
||
|
||
Синьки:
|
||
```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, який, якщо його відвідає інший користувач, може призвести до **відкриття або запису довільного локального файлу в браузері користувача**.
|
||
|
||
Синьки:
|
||
```javascript
|
||
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](https://portswigger.net/web-security/dom-based/client-side-sql-injection)
|
||
|
||
**Вразливості SQL-ін'єкцій на стороні клієнта** виникають, коли скрипт включає **дані, контрольовані атакуючими, у SQL-запит на стороні клієнта ненадійним способом**.
|
||
|
||
Синьки:
|
||
```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 ін'єкція
|
||
|
||
З: [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()
|
||
```
|
||
### Маніпуляція веб-повідомленнями
|
||
|
||
З: [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).
|
||
|
||
Синьки:
|
||
|
||
Метод `postMessage()` для надсилання веб-повідомлень може призвести до вразливостей, якщо обробник подій для отримання повідомлень обробляє вхідні дані ненадійним способом.
|
||
|
||
### Маніпуляція даними DOM
|
||
|
||
З: [https://portswigger.net/web-security/dom-based/dom-data-manipulation](https://portswigger.net/web-security/dom-based/dom-data-manipulation)
|
||
|
||
**Вразливості маніпуляції даними DOM** виникають, коли скрипт записує **дані, контрольовані атакуючими, у поле в межах DOM**, яке використовується в видимому інтерфейсі або логіці на стороні клієнта. Цю вразливість може експлуатувати атакуючий, щоб створити URL, який, якщо його відвідає інший користувач, може змінити вигляд або поведінку інтерфейсу на стороні клієнта.
|
||
|
||
Синьки:
|
||
```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()
|
||
```
|
||
### Відмова в обслуговуванні
|
||
|
||
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}}
|