SSL Sertifika Analizi Açık Port Tespiti Web Uygulama Tarama DNS Güvenlik Denetimi HTTP Başlık Analizi Yanlış Yapılandırma Tespiti Yazılım Parmak İzi Alt Alan Adı Tarama
SSL Sertifika Analizi Açık Port Tespiti Web Uygulama Tarama DNS Güvenlik Denetimi HTTP Başlık Analizi Yanlış Yapılandırma Tespiti Yazılım Parmak İzi Alt Alan Adı Tarama

Tüm Kayıtlar

Kategori İstemci Taraflı Enjeksiyon / Cross-Site Scripting
Tipik Önem Derecesi Yüksek
OWASP A03:2021 – Enjeksiyon
CWE CWE-79 – Web Sayfası Oluşturma Sırasında Girişin Hatalı Nötrleştirilmesi
Diğer adları DOM XSS, Tip-0 XSS, İstemci Taraflı XSS
Etkilenen sistemler Saldırgan kontrolündeki kaynaklardan (URL parçaları, sorgu dizeleri, postMessage, localStorage, document.referrer) veri okuyup tehlikeli DOM havuzlarına yazan istemci taraflı JavaScript kullanan web uygulamaları
İlk resmileştirme Amit Klein, 2005 — "DOM Based Cross Site Scripting or XSS of the Third Kind"

Genel Bakış

DOM Tabanlı Cross-Site Scripting (DOM XSS), güvenlik açığının sunucu tarafından üretilen HTML'de değil, tamamen istemci taraflı JavaScript kodunda bulunduğu bir XSS türüdür. Saldırı yükü hiçbir zaman sunucuya ulaşmaz; bunun yerine tarayıcının kendi JavaScript'i, saldırgan kontrolündeki verileri bir kaynaktan okur ve yeterli temizleme yapılmadan, betik çalıştırılmasına neden olan tehlikeli bir havuza iletir. Sunucu yükü hiçbir zaman görmediğinden, sunucu taraflı girdi doğrulaması ve çıktı kodlaması tek başına saldırıyı önleyemez.

DOM XSS, CWE-79 kapsamında yansıtılan ve depolanan XSS ile birlikte kataloglanmış olsa da tamamen istemci taraflı veri akışı, hem tespit hem de düzeltme stratejileri açısından onu farklı kılar. Sensagraph, bilinen kaynaklar ile tehlikeli havuzlar arasındaki istemci taraflı JavaScript veri akışlarını analiz ederek DOM XSS'i tespit eder.

Nasıl çalışır?

Saldırı zinciri iki bileşenden oluşur: saldırgan kontrolündeki verinin JavaScript'e girdiği kaynak ve temizlenmemiş veri iletildiğinde kod çalıştırılmasına veya HTML enjeksiyonuna neden olan DOM API'si ya da özelliği olan havuz.

Yaygın Kaynaklar

  • location.hash — URL parçası, sunucuya hiç iletilmez
  • location.search — sorgu dizesi parametreleri
  • location.href, location.pathname
  • document.referrer
  • window.name
  • postMessage olay verisi
  • Ele geçirilmiş bir kaynak tarafından yazılan localStorage / sessionStorage değerleri
  • Saldırgan etkisindeki veri içeren WebSocket mesajları, XMLHttpRequest / Fetch yanıtları

Yaygın Tehlikeli Havuzlar

  • element.innerHTML, element.outerHTML
  • document.write(), document.writeln()
  • eval(), setTimeout(string), setInterval(string), new Function(string)
  • element.src, element.href (javascript: URI'larına ayarlandığında)
  • location.href, location.assign(), location.replace() (açık yönlendirmeden XSS'e yükseltme)
  • jQuery yöntemleri: HTML dizeli $(), .html(), .append()

Saldırı Örneği

Aşağıdaki savunmasız JavaScript parçacığını ele alalım:

// Savunmasız kod
const name = decodeURIComponent(location.hash.slice(1));
document.getElementById('greeting').innerHTML = 'Merhaba, ' + name;

Saldırgan, https://example.com/page#<img src=x onerror=alert(document.cookie)> URL'sini hazırlayıp kurbana iletir. Kurbanın tarayıcısı sayfayı yüklediğinde, parça değeri doğrudan innerHTML'e okunur ve enjekte edilen betik, example.com bağlamında çalıştırılır — yük hiçbir zaman sunucu isteğinde görünmez.

Neden Sunucu Taraflı Savunmalar Yetersiz Kalır?

  • URL parçası (#...), HTTP spesifikasyonu (RFC 3986 §3.5) gereği sunucuya iletilmez.
  • Sunucu taraflı temizleme ve WAF'lar, hiçbir zaman almadıkları HTTP istek verileri üzerinde çalışır.
  • İçerik Güvenlik Politikası (CSP) etkiyi sınırlayabilir; ancak unsafe-eval veya unsafe-inline mevcut olduğunda ya da havuz satır içi betik çalıştırılmasını tetiklemediğinde DOM XSS'i tam olarak önleyemez.

İş etkisi

Başarılı bir DOM XSS saldırısı, saldırgana hedef kaynak altında kurbanın tarayıcısında rastgele JavaScript çalıştırma imkânı verir. Olası sonuçlar şunlardır:

  • Oturum ele geçirmeHttpOnly bayrağı olmayan oturum çerezlerinin veya JavaScript'e erişilebilir depolarda tutulan token tabanlı kimlik bilgilerinin çalınması.
  • Kimlik bilgisi toplama — güvenilir sayfalara sahte giriş formları veya tuş kaydediciler enjekte edilmesi.
  • Hesap devralma — kurban adına kimlik doğrulamalı işlemler gerçekleştirilmesi (betik aracılığıyla CSRF eşdeğeri).
  • Veri sızdırma — hassas sayfa içeriğinin, DOM durumunun veya erişilebilir API'lerin okunması ve saldırgan kontrolündeki bir uç noktaya gönderilmesi.
  • Kötü amaçlı yazılım dağıtımı — kurbanların istismar kitlerine yönlendirilmesi veya sürücüden indirme işlemlerinin başlatılması.
  • Mevzuat riski — XSS kaynaklı ihlaller GDPR, PCI DSS veya HIPAA bildirim yükümlülüklerini ve cezalarını tetikleyebilir.

DOM XSS sıklıkla URL parçasını hedef aldığından ve sunucu taraflı günlüklerde iz bırakmadığından, adli inceleme ve olay müdahalesi sunucu taraflı XSS türlerine kıyasla daha karmaşıktır.

Nasıl düzeltilir?

  1. Mümkün olan her yerde tehlikeli havuzlardan kaçının. HTML ayrıştırmayan DOM API'lerini tercih edin: düz metin eklerken element.innerHTML yerine element.textContent kullanın. DOM ağaçlarını programatik olarak oluşturmak için document.createElement() ve appendChild() kullanın.
  2. HTML havuzlarına yazmadan önce tüm verileri temizleyin. HTML çıktısı zorunluysa DOMPurify gibi güvenilir, aktif olarak desteklenen bir istemci taraflı temizleme kütüphanesi kullanın. Her zaman kısıtlayıcı biçimde yapılandırın (örn. javascript: URI'larını yasaklayın).
    // DOMPurify'ın güvenli kullanımı
    const name = decodeURIComponent(location.hash.slice(1));
    document.getElementById('greeting').innerHTML =
      'Merhaba, ' + DOMPurify.sanitize(name);
  3. Bağlama duyarlı çıktı kodlaması uygulayın. Verinin ekleneceği spesifik bağlama göre kodlayın (HTML gövdesi, HTML niteliği, JavaScript dizesi, CSS, URL). OWASP Java Encoder (sunucu taraflı) veya DOMPurify / he.js (istemci taraflı) gibi kütüphaneler bağlama duyarlı kodlama sağlar.
  4. Saldırgan kontrolündeki dizeleri JavaScript çalıştırma havuzlarına iletmekten kaçının. Kullanıcı tarafından sağlanan verileri hiçbir zaman eval(), string bağımsız değişkeniyle setTimeout/setInterval, new Function() veya document.write()'a iletmeyin.
  5. Katı bir İçerik Güvenlik Politikası (CSP) uygulayın. script-src 'nonce-{rastgele}' veya script-src 'strict-dynamic' içeren bir CSP, DOM XSS açığı mevcut olsa bile satır içi betik tabanlı istismarların büyük bölümünü engeller. unsafe-inline ve unsafe-eval yönergelerini kaldırın.
  6. postMessage kaynaklarını doğrulayın ve kısıtlayın. postMessage verilerini işlemeden önce her zaman event.origin'i bir izin listesine göre doğrulayın. postMessage verilerini hiçbir zaman doğrudan tehlikeli bir havuza iletmeyin.
  7. JavaScript çerçevelerini ve üçüncü taraf kütüphaneleri denetleyin. Birçok çerçeve (React, Angular, Vue) varsayılan olarak güvenli veri bağlama sağlar; ancak hepsi — React'ın dangerouslySetInnerHTML'i, Angular'ın bypassSecurityTrust*'ı ve Vue'nun v-html direktifi — yanlış kullanıldığında bu korumaları atlayıp DOM XSS riskini yeniden ortaya çıkaran kaçış kapıları sunar. Tüm kullanımları denetleyin.
  8. Kod incelemesi ve otomatik SAST/DAST taraması yapın. JavaScript veri akışlarında iz takibi yapabilen statik analiz araçlarını kullanarak kaynak-havuz yollarını belirleyin. Dinamik testler parça tabanlı ve postMessage tabanlı yükleri kapsamalıdır.
  9. Desteklendiği yerlerde Trusted Types benimseyin. Trusted Types tarayıcı API'si (require-trusted-types-for 'script' CSP direktifiyle zorunlu kılınır), tehlikeli DOM havuzlarına yazılan değerlerin geliştirici tanımlı bir ilke tarafından üretilen bir Trusted Type nesnesinden geçmesini zorunlu kılar; bu da DOM XSS enjeksiyonunu yapısal olarak çok daha zorlaştırır.

Referanslar

Sıkça sorulan sorular

Yansıtılan ve depolanan XSS'de kötü amaçlı yük sunucu tarafından işlenip döndürülür (veya depolanarak daha sonra döndürülür) ve enjeksiyon noktası sunucu tarafından üretilen HTML'dedir. DOM tabanlı XSS'de ise yük hiçbir zaman sunucuya ulaşmaz; tarayıcının kendi JavaScript'i, saldırgan kontrolündeki verileri bir kaynaktan (örn. URL parçası) okuyup tehlikeli bir DOM havuzuna yazarak çalıştırmayı tamamen istemci tarafında gerçekleştirir.

Güvenilir biçimde önleyemez. WAF, HTTP istek verilerini inceler. Saldırı yükü URL parçası (#'den sonraki kısım) aracılığıyla iletiliyorsa, sunucuya gönderilen HTTP isteğinde hiç yer almaz ve WAF onu hiçbir zaman göremez. Sorgu dizesi tabanlı DOM XSS için bile WAF, istemci taraflı JavaScript'in veriyi nasıl işlediğini analiz edemez. Sunucu taraflı kontroller, istemci taraflı temizleme ve katı bir İçerik Güvenlik Politikasıyla desteklenmelidir.

Modern JavaScript çerçeveleri, standart enterpolasyon bağlamlarında çıktıyı otomatik olarak kodlayan güvenli-varsayılan veri bağlama kullanır. Ancak tüm büyük çerçeveler bu korumaları atlayıp DOM XSS riskini yeniden ortaya çıkaran kaçış kapıları sunar: React'ın dangerouslySetInnerHTML'i, Angular'ın bypassSecurityTrustHtml'i ve Vue'nun v-html direktifi. Bu kaçış kapılarını kullanan uygulamalar, veriyi iletmeden önce manuel olarak temizlemelidir.

Trusted Types, tehlikeli DOM havuzlarına (innerHTML veya eval gibi) yazılan değerlerin geliştirici tanımlı bir ilke tarafından üretilen Trusted Type nesnesine sarılmasını zorunlu kılan bir tarayıcı API'sidir (require-trusted-types-for 'script' Content Security Policy direktifiyle zorunlu hâle getirilir). Bu, yeni DOM XSS havuzlarının eklenmesini yapısal olarak zorlaştırır ve tüm HTML enjeksiyon noktalarının merkezi denetimini sağlar.

DOM XSS, kurbanın hazırlanmış bir URL yüklemesini veya kötü amaçlı bir postMessage almasını gerektirir; bu genellikle sosyal mühendislik (kimlik avı, kötü amaçlı bağlantı) içerir. Herhangi bir kullanıcı sayfayı ziyaret ettiğinde otomatik olarak tetiklenen depolanan XSS'in aksine, DOM XSS saldırıları genellikle hedeflidir ve belirli kurbanlara yük iletilmesini gerektirir. Ancak localStorage'a veya bir veritabanına yazılan bir değerin sonraki ziyaretlerde tehlikeli bir havuza okunduğu depolanan DOM XSS, sonraki ziyaretlerde otomatik olarak tetiklenebilir.