mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
301 lines
22 KiB
Markdown
301 lines
22 KiB
Markdown
# DOM XSS
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|
|
|
|
## DOM-Schwachstellen
|
|
|
|
DOM-Schwachstellen treten auf, wenn Daten aus von Angreifern kontrollierten **Quellen** (wie `location.search`, `document.referrer` oder `document.cookie`) unsicher an **Senken** übertragen werden. Senken sind Funktionen oder Objekte (z. B. `eval()`, `document.body.innerHTML`), die schädlichen Inhalt ausführen oder rendern können, wenn sie mit bösartigen Daten versorgt werden.
|
|
|
|
- **Quellen** sind Eingaben, die von Angreifern manipuliert werden können, einschließlich URLs, Cookies und Webnachrichten.
|
|
- **Senken** sind potenziell gefährliche Endpunkte, an denen bösartige Daten zu negativen Auswirkungen führen können, wie z. B. der Ausführung von Skripten.
|
|
|
|
Das Risiko entsteht, wenn Daten von einer Quelle zu einer Senke fließen, ohne dass eine ordnungsgemäße Validierung oder Bereinigung erfolgt, was Angriffe wie XSS ermöglicht.
|
|
|
|
> [!NOTE]
|
|
> **Eine aktuellere Liste von Quellen und Senken finden Sie unter** [**https://github.com/wisec/domxsswiki/wiki**](https://github.com/wisec/domxsswiki/wiki)
|
|
|
|
**Häufige Quellen:**
|
|
```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
|
|
```
|
|
**Gemeinsame Sinks:**
|
|
|
|
| [**Open Redirect**](dom-xss.md#open-redirect) | [**Javascript Injection**](dom-xss.md#javascript-injection) | [**DOM-Datenmanipulation**](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` | **\`\`**[**Manipulation des lokalen Dateipfads**](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()` |
|
|
| **\`\`**[**Manipulation von Ajax-Anfragen**](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()` | [**Link-Manipulation**](dom-xss.md#link-manipulation) | `someDOMElement.innerHTML` | `jQuery.parseHTML()` |
|
|
| `jQuery.globalEval()` | `someDOMElement.href` | `someDOMElement.outerHTML` | `$.parseHTML()` |
|
|
| `$.globalEval()` | `someDOMElement.src` | `someDOMElement.insertAdjacentHTML` | [**Client-seitige JSON-Injection**](dom-xss.md#client-side-sql-injection) |
|
|
| **\`\`**[**Manipulation des HTML5-Speichers**](dom-xss.md#html-5-storage-manipulation) | `someDOMElement.action` | `someDOMElement.onevent` | `JSON.parse()` |
|
|
| `sessionStorage.setItem()` | [**XPath-Injection**](dom-xss.md#xpath-injection) | `document.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**](dom-xss.md#cookie-manipulation) |
|
|
| `requestFileSystem()` | **\`\`**[**Manipulation der Dokumentdomäne**](dom-xss.md#document-domain-manipulation) | `document.implementation.createHTMLDocument()` | `document.cookie` |
|
|
| `RegExp()` | `document.domain` | `history.pushState()` | [**WebSocket-URL-Vergiftung**](dom-xss.md#websocket-url-poisoning) |
|
|
| [**Client-seitige SQL-Injection**](dom-xss.md#client-side-sql-injection) | [**Manipulation von Web-Nachrichten**](dom-xss.md#web-message-manipulation) | `history.replaceState()` | `WebSocket` |
|
|
| `executeSql()` | `postMessage()` | \`\` | \`\` |
|
|
|
|
Der **`innerHTML`** Sink akzeptiert in modernen Browsern keine `script`-Elemente, noch werden `svg onload`-Ereignisse ausgelöst. Das bedeutet, dass Sie alternative Elemente wie `img` oder `iframe` verwenden müssen.
|
|
|
|
Diese Art von XSS ist wahrscheinlich die **schwierigste zu finden**, da Sie den JS-Code durchsuchen müssen, um zu sehen, ob er **irgendein Objekt verwendet**, dessen **Wert Sie kontrollieren**, und in diesem Fall prüfen müssen, ob es **irgendeine Möglichkeit gibt,** es zu missbrauchen, um beliebigen JS auszuführen.
|
|
|
|
## Werkzeuge, um sie zu finden
|
|
|
|
- [https://github.com/mozilla/eslint-plugin-no-unsanitized](https://github.com/mozilla/eslint-plugin-no-unsanitized)
|
|
- Browsererweiterung, um jede Daten zu überprüfen, die einen potenziellen Sink erreicht: [https://github.com/kevin-mizu/domloggerpp](https://github.com/kevin-mizu/domloggerpp)
|
|
|
|
## Beispiele
|
|
|
|
### Open Redirect
|
|
|
|
Von: [https://portswigger.net/web-security/dom-based/open-redirection](https://portswigger.net/web-security/dom-based/open-redirection)
|
|
|
|
**Open Redirect-Schwachstellen im DOM** treten auf, wenn ein Skript Daten schreibt, die ein Angreifer kontrollieren kann, in einen Sink, der in der Lage ist, die Navigation über Domains hinweg zu initiieren.
|
|
|
|
Es ist entscheidend zu verstehen, dass die Ausführung beliebigen Codes, wie **`javascript:alert(1)`**, möglich ist, wenn Sie die Kontrolle über den Anfang der URL haben, wo die Umleitung erfolgt.
|
|
|
|
Sinks:
|
|
```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()
|
|
```
|
|
### Cookie-Manipulation
|
|
|
|
Von: [https://portswigger.net/web-security/dom-based/cookie-manipulation](https://portswigger.net/web-security/dom-based/cookie-manipulation)
|
|
|
|
DOM-basierte Cookie-Manipulationsanfälligkeiten treten auf, wenn ein Skript Daten, die von einem Angreifer kontrolliert werden können, in den Wert eines Cookies einfügt. Diese Anfälligkeit kann zu unerwartetem Verhalten der Webseite führen, wenn das Cookie innerhalb der Seite verwendet wird. Darüber hinaus kann sie ausgenutzt werden, um einen Session-Fixation-Angriff durchzuführen, wenn das Cookie an der Verfolgung von Benutzersitzungen beteiligt ist. Die primäre Senke, die mit dieser Anfälligkeit verbunden ist, ist:
|
|
|
|
Senken:
|
|
```javascript
|
|
document.cookie
|
|
```
|
|
### JavaScript-Injektion
|
|
|
|
Von: [https://portswigger.net/web-security/dom-based/javascript-injection](https://portswigger.net/web-security/dom-based/javascript-injection)
|
|
|
|
DOM-basierte JavaScript-Injektionsanfälligkeiten entstehen, wenn ein Skript Daten, die von einem Angreifer kontrolliert werden können, als JavaScript-Code ausführt.
|
|
|
|
Sinks:
|
|
```javascript
|
|
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](https://portswigger.net/web-security/dom-based/document-domain-manipulation)
|
|
|
|
**Dokument-Domain-Manipulationsanfälligkeiten** treten auf, wenn ein Skript die `document.domain`-Eigenschaft mit Daten festlegt, die ein Angreifer kontrollieren kann.
|
|
|
|
Die `document.domain`-Eigenschaft spielt eine **Schlüsselrolle** bei der **Durchsetzung** der **Same-Origin-Policy** durch Browser. Wenn zwei Seiten aus unterschiedlichen Ursprüngen ihre `document.domain` auf den **gleichen Wert** setzen, können sie ohne Einschränkungen interagieren. Obwohl Browser bestimmte **Grenzen** für die Werte, die `document.domain` zugewiesen werden können, auferlegen, um die Zuweisung völlig nicht verwandter Werte zum tatsächlichen Seitenursprung zu verhindern, gibt es Ausnahmen. Typischerweise erlauben Browser die Verwendung von **Kind**- oder **Eltern-Domains**.
|
|
|
|
Sinks:
|
|
```javascript
|
|
document.domain
|
|
```
|
|
### WebSocket-URL-Poisoning
|
|
|
|
Von: [https://portswigger.net/web-security/dom-based/websocket-url-poisoning](https://portswigger.net/web-security/dom-based/websocket-url-poisoning)
|
|
|
|
**WebSocket-URL-Poisoning** tritt auf, wenn ein Skript **kontrollierbare Daten als Ziel-URL** für eine WebSocket-Verbindung verwendet.
|
|
|
|
Sinks:
|
|
|
|
Der `WebSocket`-Konstruktor kann zu WebSocket-URL-Poisoning-Schwachstellen führen.
|
|
|
|
### Link-Manipulation
|
|
|
|
Von: [https://portswigger.net/web-security/dom-based/link-manipulation](https://portswigger.net/web-security/dom-based/link-manipulation)
|
|
|
|
**DOM-basierte Link-Manipulationsschwachstellen** entstehen, wenn ein Skript **angreiferkontrollierbare Daten an ein Navigationsziel** innerhalb der aktuellen Seite schreibt, wie z.B. einen klickbaren Link oder die Einreichungs-URL eines Formulars.
|
|
|
|
Sinks:
|
|
```javascript
|
|
someDOMElement.href
|
|
someDOMElement.src
|
|
someDOMElement.action
|
|
```
|
|
### Ajax-Anforderungsmanipulation
|
|
|
|
Von: [https://portswigger.net/web-security/dom-based/ajax-request-header-manipulation](https://portswigger.net/web-security/dom-based/ajax-request-header-manipulation)
|
|
|
|
**Schwachstellen bei der Ajax-Anforderungsmanipulation** entstehen, wenn ein Skript **angreiferkontrollierbare Daten in eine Ajax-Anforderung** schreibt, die mit einem `XmlHttpRequest`-Objekt ausgegeben wird.
|
|
|
|
Sinks:
|
|
```javascript
|
|
XMLHttpRequest.setRequestHeader()
|
|
XMLHttpRequest.open()
|
|
XMLHttpRequest.send()
|
|
jQuery.globalEval()
|
|
$.globalEval()
|
|
```
|
|
### Lokale Dateipfadmanipulation
|
|
|
|
Von: [https://portswigger.net/web-security/dom-based/local-file-path-manipulation](https://portswigger.net/web-security/dom-based/local-file-path-manipulation)
|
|
|
|
**Schwachstellen bei der lokalen Dateipfadmanipulation** entstehen, wenn ein Skript **vom Angreifer kontrollierbare Daten an eine Datei-Verarbeitungs-API** als `filename`-Parameter übergibt. Diese Schwachstelle kann von einem Angreifer ausgenutzt werden, um eine URL zu konstruieren, die, wenn sie von einem anderen Benutzer besucht wird, dazu führen könnte, dass **der Browser des Benutzers eine beliebige lokale Datei öffnet oder schreibt**.
|
|
|
|
Sinks:
|
|
```javascript
|
|
FileReader.readAsArrayBuffer()
|
|
FileReader.readAsBinaryString()
|
|
FileReader.readAsDataURL()
|
|
FileReader.readAsText()
|
|
FileReader.readAsFile()
|
|
FileReader.root.getFile()
|
|
FileReader.root.getFile()
|
|
```
|
|
### Client-Side SQL-Injection
|
|
|
|
Von: [https://portswigger.net/web-security/dom-based/client-side-sql-injection](https://portswigger.net/web-security/dom-based/client-side-sql-injection)
|
|
|
|
**Client-side SQL-Injection-Schwachstellen** treten auf, wenn ein Skript **angreiferkontrollierte Daten auf unsichere Weise in eine clientseitige SQL-Abfrage einfügt**.
|
|
|
|
Sinks:
|
|
```javascript
|
|
executeSql()
|
|
```
|
|
### HTML5-Speicher-Manipulation
|
|
|
|
Von: [https://portswigger.net/web-security/dom-based/html5-storage-manipulation](https://portswigger.net/web-security/dom-based/html5-storage-manipulation)
|
|
|
|
**HTML5-Speicher-Manipulationsanfälligkeiten** entstehen, wenn ein Skript **angreiferkontrollierte Daten im HTML5-Speicher des Webbrowsers** (`localStorage` oder `sessionStorage`) **speichert**. Während diese Aktion an sich keine Sicherheitsanfälligkeit darstellt, wird sie problematisch, wenn die Anwendung anschließend **die gespeicherten Daten liest und unsicher verarbeitet**. Dies könnte es einem Angreifer ermöglichen, den Speichermechanismus auszunutzen, um andere DOM-basierte Angriffe durchzuführen, wie z.B. Cross-Site-Scripting und JavaScript-Injection.
|
|
|
|
Sinks:
|
|
```javascript
|
|
sessionStorage.setItem()
|
|
localStorage.setItem()
|
|
```
|
|
### XPath-Injection
|
|
|
|
Von: [https://portswigger.net/web-security/dom-based/client-side-xpath-injection](https://portswigger.net/web-security/dom-based/client-side-xpath-injection)
|
|
|
|
**DOM-basierte XPath-Injektionsanfälligkeiten** treten auf, wenn ein Skript **angreiferkontrollierte Daten in eine XPath-Abfrage** einfügt.
|
|
|
|
Sinks:
|
|
```javascript
|
|
document.evaluate()
|
|
someDOMElement.evaluate()
|
|
```
|
|
### Client-seitige JSON-Injektion
|
|
|
|
From: [https://portswigger.net/web-security/dom-based/client-side-json-injection](https://portswigger.net/web-security/dom-based/client-side-json-injection)
|
|
|
|
**DOM-basierte JSON-Injektionsanfälligkeiten** treten auf, wenn ein Skript **von einem Angreifer kontrollierte Daten in einen String einfügt, der als JSON-Datenstruktur geparst und dann von der Anwendung verarbeitet wird**.
|
|
|
|
Sinks:
|
|
```javascript
|
|
JSON.parse()
|
|
jQuery.parseJSON()
|
|
$.parseJSON()
|
|
```
|
|
### Web-Nachrichtenmanipulation
|
|
|
|
Von: [https://portswigger.net/web-security/dom-based/web-message-manipulation](https://portswigger.net/web-security/dom-based/web-message-manipulation)
|
|
|
|
**Web-Nachrichtenanfälligkeiten** entstehen, wenn ein Skript **vom Angreifer kontrollierbare Daten als Web-Nachricht an ein anderes Dokument** im Browser sendet. Ein **Beispiel** für anfällige Web-Nachrichtenmanipulation findet sich in [PortSwiggers Web Security Academy](https://portswigger.net/web-security/dom-based/controlling-the-web-message-source).
|
|
|
|
Sinks:
|
|
|
|
Die `postMessage()`-Methode zum Senden von Web-Nachrichten kann zu Sicherheitsanfälligkeiten führen, wenn der Ereignislistener für den Empfang von Nachrichten die eingehenden Daten auf unsichere Weise verarbeitet.
|
|
|
|
### DOM-Datenmanipulation
|
|
|
|
Von: [https://portswigger.net/web-security/dom-based/dom-data-manipulation](https://portswigger.net/web-security/dom-based/dom-data-manipulation)
|
|
|
|
**DOM-Datenmanipulationsanfälligkeiten** entstehen, wenn ein Skript **vom Angreifer kontrollierbare Daten in ein Feld innerhalb des DOM** schreibt, das in der sichtbaren UI oder der clientseitigen Logik verwendet wird. Diese Sicherheitsanfälligkeit kann von einem Angreifer ausgenutzt werden, um eine URL zu konstruieren, die, wenn sie von einem anderen Benutzer besucht wird, das Erscheinungsbild oder Verhalten der clientseitigen UI ändern kann.
|
|
|
|
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-basierte Denial-of-Service-Schwachstellen** treten auf, wenn ein Skript **angreiferkontrollierte Daten unsicher an eine problematische Plattform-API übergibt**. Dazu gehören APIs, die, wenn sie aufgerufen werden, dazu führen können, dass der Computer des Benutzers **übermäßige Mengen an CPU oder Speicherplatz** verbraucht. Solche Schwachstellen können erhebliche Nebenwirkungen haben, wie z.B. dass der Browser die Funktionalität der Website einschränkt, indem er Versuche, Daten in `localStorage` zu speichern, ablehnt oder beschäftigte Skripte beendet.
|
|
|
|
Sinks:
|
|
```javascript
|
|
requestFileSystem()
|
|
RegExp()
|
|
```
|
|
## Dom Clobbering
|
|
|
|
{{#ref}}
|
|
dom-clobbering.md
|
|
{{#endref}}
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|