Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 44

DOM Clobbering ile Güvenlik Zafiyetlerini Belirleme

Recommended resources

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:

  • id niteliği: Bir elemana verilen id (örneğin, <div id="config">), genellikle doğrudan window.config şeklinde global bir değişken oluşturur. Eğer kodda window.config adında bir nesne kullanılıyorsa, artık bu değişken bir HTMLDivElement nesnesine işaret edecektir.
  • name niteliği: Bu nitelik daha da ilginç davranışlara yol açabilir. Aynı name değerine sahip birden fazla eleman (örneğin, <a name="user">, <input name="user">), window.user adında bir HTMLCollection (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.

Bu görsel, `<a id=CONFIG name=test>` ve `<a id=testPath name=protocol>` gibi elemanların tarayıcı tarafından yorumlanarak sırasıyla `window.CONFIG` ve `window.testPath` adında `HTMLCollection` nesneleri oluşturduğunu göstermektedir. Bu, DOM Clobbering'in temel mekanizmasını görselleştirir.

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?

  1. var someObject = window.someObject || {}; satırı çalıştığında, window.someObject artık undefined değildir. <a id="someObject"> sayesinde bir HTMLCollection nesnesidir. Bu yüzden || {} kısmı çalışmaz ve someObject değişkeni bu HTMLCollection'a eşitlenir.
  2. Bu HTMLCollection aynı zamanda url adında bir özelliğe sahiptir (ikinci <a> etiketinin name niteliği sayesinde). Bu özelliğin değeri ise ikinci <a> elemanının kendisidir.
  3. someObject.url ifadesi bu ikinci <a> elemanını döndürür. Bir <a> elemanı string olarak kullanıldığında, href niteliğinin değerini verir.
  4. Sonuç olarak fetch fonksiyonu, geliştiricinin beklediği güvenli URL yerine https://malicious-website.com/malicious.js adresine 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.

Bu konsol çıktıları, başlangıçta boş olan `someObject` değişkeninin, HTML enjeksiyonu ile önce bir `HTMLCollection`'a, ardından da `url` özelliğine sahip bir nesneye nasıl dönüştürüldüğünü ve `someObject.url.href` ile kötü niyetli URL'ye nasıl erişildiğini adım adım 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:

  1. 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.querySelector gibi DOM API'lerini çağıran kodlar da, bu fonksiyonların kendisi clobber'lanabileceğinden dolaylı hedeflerdir.
  2. 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)
    • postMessage ile alınan ve innerHTML'e yazdırılan veriler
  3. 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 id ve name niteliklerine izin veriyor mu? Kütüphanenin kendisi, Lab-7'deki HTMLJanitor örneğinde olduğu gibi, DOM Clobbering'e karşı savunmasız olabilir mi?

  4. Etkiyi Değerlendirin: Clobber'lanan değişken nerede kullanılıyor?

    • Bir script etiketinin src'sini oluşturmak için mi? (Potansiyel XSS)
    • Bir <a> etiketinin href'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)

Ö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 id ve name niteliklerinden 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 HTMLCollection kullanarak 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.