Giriş
DOM tabanlı bir XSS hile sayfası başvurulacak referansınız istemci tarafı komut dosyası enjeksiyonuna karşı korumayı bulmak, önlemek ve otomatikleştirmek istediğinizde. Özünde: kullanıcı kontrollü girdinin (bir kaynak) tehlikeli bir API'ye (a Lavabo), güvenli kalıplarla değiştirin (kullanım textContent, createElementveya sanitizer'lar) ve kontrolleri derleme, çalışma zamanı ve pentest iş akışınıza entegre edin. DOM XSS tamamen tarayıcıda gerçekleştiğinden ve birçok geleneksel sunucu tarafı filtresini atladığından, ön ucunuz son savunma hattı haline gelir ve çoğu ekibin hala otomasyondan yoksun olduğu yerdir.
DOM Tabanlı XSS nedir ve neden önemlidir?
PortSwigger'a göre, DOM tabanlı siteler arası komut dosyası oluşturma şu durumlarda ortaya çıkar "JavaScript, URL gibi saldırgan tarafından kontrol edilebilen bir kaynaktan veri alır ve bu verileri dinamik kod yürütmeyi destekleyen eval() veya innerHTML." portswigger.net OWASP DOM tabanlı XSS Önleme Hile Sayfası, depolanmış/yansıtılmış XSS'den temel farkın şu olduğunun altını çizmektedir çalışma zamanı istemci tarafı enjeksiyonu. cheatsheetseries.owasp.org+1
Modern uygulamalarda - Tek Sayfa Uygulamaları (SPA'lar), üçüncü taraf widget'ların yoğun kullanımı, dinamik DOM oluşturma - risk artar: yükler sunucu günlüklerinize asla ulaşmayabilir, geleneksel WAF'lar bunları gözden kaçırabilir ve geliştiriciler genellikle yeterince dikkate almaz parça tanımlayıcıları, postMessage akışlarıveya pencere.adıtüm ortak kaynaklar. Bu değişimin farkına varmak, güvenlik olgunluğunuzu ölçmeye yönelik ilk adımdır.
Tehdidin haritalanması: kaynaklar → yutaklar
Güvenli kodlama, aşağıdakilerin zihinsel bir haritasıyla başlar kaynaklar (saldırgan girdisinin girdiği yer) ve lavabolar (yürütmenin gerçekleştiği yer). Bir güvenlik blogu özetlemektedir: "Kaynak, bir web sayfasında kullanıcı girdisinin eklenebileceği herhangi bir yerdir... Lavabo, kaynağa eklenen verilerin gittiği yerdir... ve sterilize edilmezse DOM tabanlı bir XSS açığına yol açabilir." Orta
Aşağıda, iş istasyonunuzda ve inceleme kontrol listelerinizde bulundurmanız gereken kompakt bir tablo bulunmaktadır:
| Kaynak (giriş noktası) | Lavabo (tehlikeli API) |
|---|---|
| location.hash, location.search, URLSearchParams | innerHTML, insertAdjacentHTML, outerHTML |
| postMessage, pencere.adı | eval(), new Function(), setTimeout(string) |
| document.referrer, localStorage, sessionStorage | setAttribute('on...'), element.src = ... |
| İncelenmemiş üçüncü taraf widget verileri | Herhangi bir DOM ekleme veya örtük kod yürütme |
OWASP'ın da vurguladığı gibi, tek bir teknik XSS'yi önleyemez: uygun lavaboları, kodlamayı, sanitizasyonu ve güvenli API'leri birleştirmelisiniz. cheatsheetseries.owasp.org
Kod ve Düzeltmelerle Gerçek Dünya Saldırı Modelleri
Örnek A - URL parçası aracılığıyla jQuery seçici enjeksiyonu
Savunmasız snippet:
js
$(window).on('hashchange', () => {
const hedef = $(konum.hash); // kullanıcı kontrollü
target[0].scrollIntoView();
});
Bir saldırgan şunları yapabilir https://site/page.html#<img src="x" onerror="alert(1)"> - jQuery hash'i HTML/seçici olarak ele alır ve onerror Tetikleyiciler.
Düzelt:
js
const raw = location.hash.slice(1);
const safeId = /^[A-Za-z0-9_-]+$/.test(raw) ? raw : null;
if (safeId) {
const hedef = document.getElementById(safeId);
if (target) target.scrollIntoView();
}
Anahtar: doğrulayın, karmayı HTML değil tanımlayıcı olarak ele alın.
Örnek B - postMessage → eval zinciri
Savunmasız snippet:
js
window.addEventListener('mesaj', e => {
eval(e.data); // tehlikeli
});
Düzeltilmiş versiyon:
window.addEventListener('mesaj', olay => {
if (event.origin !== '') return;
dene {
const msg = JSON.parse(event.data);
handleMessage(msg);
} catch {
console.warn('Geçersiz mesaj biçimi');
}
});
Kaçının eval, kaynağını kontrol edin, güvenli ayrıştırma kullanın.
Örnek C - Markdown bağlamında Editör/Önizleme XSS
Savunmasız:
js
preview.innerHTML = marked(userInput);
Güvenli:
js
import DOMPurify from 'dompurify';
const dirty = marked(userInput);
const clean = DOMPurify.sanitize(dirty);
preview.innerHTML = clean;
Kullanıcı tarafından oluşturulan HTML'ye izin verirken, sanitizasyon gereklidir.
Dağıtılabilir Uygulamalar: operasyonel hale getirmek
Güvenli DOM yardımcısı - safe-dom.js
js
import DOMPurify from 'dompurify';
export function setSafeHTML(el, dirty) {
const clean = DOMPurify.sanitize(dirty, {
İZİN VERİLEN ETİKETLER: ['b','i','a','p','ul','li','code','pre','img'],
ALLOWED_ATTR: ['href','src','alt','title','rel'],
FORBID_ATTR: ['onerror','onclick','style']
});
el.innerHTML = clean;
}
export function setText(el, text) {
el.textContent = String(text ?? '');
}
export function safeSetAttribute(el, name, val) {
if (/^on/i.test(name)) throw new Error('Event handler attribute not allowed');
el.setAttribute(name, String(val));
}
Güvenli DOM işlemlerini merkezileştirmek ve insan hatalarını azaltmak için bu kütüphaneyi kullanın.
Statik uygulama - ESLint örneği
js
// .eslintrc.js
kurallar: {
'no-restricted-syntax': [
'hata',
{ seçici: "AssignmentExpression[left.property.name='innerHTML']", mesaj: "safe-dom.setSafeHTML veya textContent kullanın." },
{ seçici: "CallExpression[callee.name='eval']", mesaj: "Avoid eval()" },
{ seçici: "CallExpression[callee.property.name='write']", mesaj: "Avoid document.write()" }
]
}
Pre-commit kancaları ile birleştirin (husky, lint-staged) tehlikeli kalıpları engellemek için.
CI / Puppeteer testi - GitHub Actions
.github/workflows/dom-xss.yml bir Puppeteer testini tetikler:
// tests/puppeteer/dom-xss-test.js
js
const puppeteer = require('puppeteer');
(async ()=>{
const browser = await puppeteer.launch();
const sayfa = await browser.newPage();
const logs = [];
page.on('console', msg => logs.push(msg.text()));
await page.goto(${URL}/page.html#<img src="x" onerror="console.log("xss")">);
await page.waitForTimeout(1000);
if (logs.some(l=>l.includes('XSS'))) process.exit(2);
await browser.close();
})();
Tespit üzerine başarısız yapı.
Çalışma zamanı izleme - MutationObserver
js
(function(){
const obs = new MutationObserver(muts=>{
muts.forEach(m=>{
m.addedNodes.forEach(n=>{
if(n.nodeType===1){
const html = n.innerHTML || '';
if(/on(error|click|load)|<script\\b/i.test(html)){
navigator.sendBeacon('/_monitoring/xss', JSON.stringify({
url: location.href, snippet: html.slice(0,200)
}));
}
}
});
});
});
obs.observe(document.documentElement, {childList:true, subtree:true});
})();
Beklenmedik DOM enjeksiyonlarını uyarmak için evrelemede kullanışlıdır.
Tarayıcı güvenliği güçlendirme - CSP ve Güvenilir Türler
CSP başlığı:
pgsql
Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-XYZ'; object-src 'none'; base-uri 'self';
Güvenilir Türler parçacığı:
js
window.trustedTypes?.createPolicy('safePolicy', {
createHTML: s => { throw new Error('Doğrudan HTML ataması engellendi'); },
createScript: s => { throw new Error('Doğrudan komut dosyası oluşturma engellendi'); }
});
Bu, güvenilmeyen lavaboları varsayılan olarak reddeder.
Üçüncü taraf senaryo güvenliği - SRI
bash
openssl dgst -sha384 -binary vendor.js | openssl base64 -A
Kullanım <script src="vendor.js" integrity="sha384‑..." crossorigin="anonymous"></script> sabitlemek ve doğrulamak için.
Otomasyon için Penligent ile entegrasyon
Ekibiniz Penligent kullanıyorsa, DOM XSS korumanızı sürekli bir boru hattına yükseltebilirsiniz. Penligent'ın araştırma makalesi şunları belirtiyor "DOM tabanlı XSS'yi çalışma zamanı kusur izleme yoluyla tespit etmek ... sunucu tarafı teknikleri istemci tarafı enjeksiyonunu güvenilir bir şekilde yakalayamaz." Penligent
Örnek iş akışı:
- CI'da kural seti ile bir Penligent taraması tetikleyin
dom-xssgibi yükler sağlayarak#<img src="x" onerror="alert(1)">. - Penligent başsız akışları yürütür, PoC oluşturur, bulguları webhook aracılığıyla döndürür.
- CI bulguları analiz eder: önem derecesi ≥ yüksekse, derleme başarısız olur ve PR'ye yük + lavabo + düzeltme önerisi ile açıklama eklenir (ör.
innerHTMLilesafe-dom.setSafeHTML). - Geliştiriciler düzeltiyor, CI'ı tekrar çalıştırıyor, yalnızca yeşil olduğunda birleştiriyor.
Bu, döngüyü kapatır: referanstan (bu kopya sayfası) → kod politikası → otomatik algılama → organize düzeltme.
Sonuç
Ön uç artık "sadece kullanıcı arayüzü" değildir. O artık bir saldırı yüzeyi. Bu kopya sayfası, istemci tarafı enjeksiyonu anlama, tehlikeli havuzları değiştirme, güvenli yardımcı kütüphaneler oluşturma, statik/CI/çalışma zamanı algılamayı dağıtma ve Penligent gibi bir platformla otomatikleştirme konularında size yol gösterir. Sonraki adımlarınız: kod tabanınızı yasaklı havuzlar için tarayın (innerHTML, eval), bir güvenli-dom kütüphane, lint kurallarını uygulamak, başsız testleri ve gerçek pentest mantığını entegre etmek, üretim / sahnelemeyi izlemek ve üçüncü taraf kaynaklarını sabitlemek. DOM XSS'i korumak, bunu yapmakla ilgilidir imkansız Sadece şansa güvenerek değil.

