DOM Tabanlı XSS Nedir?
Markanız için 300X300 alan.
DOM Tabanlı XSS ya da diğer adıyla "type-0 XSS" bir XSS saldırısı olup saldırı kurbanın tarayıcısındaki DOM 'çevresinde' değişiklik gerçekleştirir yani tarayıcı taraflı kod 'istenmeyen' sonuçlara yol açacak biçimde çalışır. Bu durumda, belgenin kendisinde (HTTP yanıtında) bir değişiklik yoktur, sorun, sunucunun yanıtı ile gelen kodların tarayıcı tarafında -DOM'da- yaptığı "zararlı" değişiklikler gerçekleştiriyor olmasıdır.
DOM Tabanlı XSS'te, sunucu taraflı hatalar yüzünden gerçekleşen sunucudan dönen zararlı yanıtın sorunlara yol açtığı Yerleşik ve Yansıyan XSS saldırı yöntemine karşıt bir durum vardır.
David Wichers DOM Tabanlı XSS saldırısını daha doğru tanımlayıp CLIENT SIDE XSS (istemci taraflı XSS) (type-0.29) olarak yeniden sınıflandırma üzerine çalışıyor.
DOM Tabanlı XSS Nasıl Yapılır?
Dil Seçin :
<select><script>
document.write("<optionvalue=1>"+document.location.href.substring(document.location.href.indexOf("default=")+8)+"</option>");
document.write("<option value=2>English</option>");
</script></select>
kodunu içeren belgeye
https://SonDevrim.com/?lang=TR
bağlantısı ile erişilirse sonuç :
<option value=1>default=TR</option>
olur.
Ama aynı sayfaya
https://SonDevrim.com/?lang=<script>alert(document.cookie)</script>
bağlantısı ile erişilirse DOM tabanlı XSS gerçekleşir.
(<script>alert(document.cookie)</script> kodu köprü metine yerleştirilir ve tarayıcı tarafından çalıştırılır.)
<option value=1>default=<script>alert(document.cookie)</script></option>
Adobe Reader'ın tarayıcı eklentilerinde 2006 yılında bulunan DOM Tabanlı XSS açığı :
https://SonDevrim.com/dosya/blog/birDosya.pdf#birAd=javascript:saldırgan_betik_buraya
Tamgaların nasıl kaçıldığı XSS Güvenlik İlkeleri sayfasında gösterildi.
DOM Tabanlı XSS Nasıl Önlenir ? Kural 1 - Köprü Metin'e Ekleme Yapılıyorsa Önce HTML Ardından JavaScript Kaçılmalı
DOM Tabanlı XSS saldırılarını önlemek için; HTML içeriğine bir ekleme yapılıyorsa önce HTML ardından JavaScript kaçılmalı.
DOM Tabanlı XSS Nasıl Önlenir ? Kural 2 - HTML Özniteliğine Ekleme Yapılıyorsa JavaScript Kaçılmalı
DOM Tabanlı XSS saldırılarının önlemek için; olay dinleyicileri, CSS ve URL ile ligili öznitelikler dışında kalan özniteliklere veri eklenirken JavaScript kaçılmalı.
Özel tamgalar kullanılarak özniteliğin kırılmasıyla (sonlandırılmasıyla) HTML etiketlerine yeni HTML Etiket Özniteliklerinden eklenerek DOM Tabanlı XSS başarılabilir.
DOM Tabanlı XSS Nasıl Önlenir ? Kural 3 - Olay Dinleyicilerine ve JavaScript'e Güvenilmeyen Veri Eklerken Dikkatli Olun
JavaScript -HTML'nin tersine- ECMAScript ölçünlerine sahip bir dil olduğundan aynı komutlar birden fazla değişik biçimde yazılabilir. Bu JavaScript Encode'nin her zaman işe yaramayacağı anlamına geliyor.
Her iki kod da aynı olmasına rağmen
HTML'de
<a href="...">
çalışırken
<a href=... >
çalışmaz.
JavaScript'te aynı deyiş birden farklı biçimde yazılırsa hepsi çalışır.
Bundan dolayı JavaScript'e güvenilmeyen veri eklenirken aşırı özenli davranılmalı.
x'in herhangi bir <a>
etiketi olduğu var sayıldığında
x.setAttribute("onclick", "\u0061\u006c\u0065\u0072\u0074\u0028\u0032\u0032\u0029");
JavaScript ile x etiketine eklenirse onclick
'e atanan değer 'öznitelik türüne' dönüştürülür ve çalıştırılır ve bu 'çalıştırma' durumu saldırının başarıya ulaşmasını sağlar.
Ancak aynı kod
document.getElementById("bb").onclick = "\u0061\u006c\u0065\u0072\u0074\u0028\u0037\u0029";
biçiminde yazılsaydı, onclick
olayına atanan değer -düz- metin türünden olduğundan saldırı başarısız olurdu.
Veb Geliştiriciler dinleyicilerin daha yeni bir yöntem olan addEvenListener
yöntemiyle eklenmesini öneriyorlar.
x.addEventListener("click", "\u0061\u006c\u0065\u0072\u0074\u0028\u0032\u0032\u0029");
Dinleyici bu biçimde eklenirse çalıştırılmaz.
// Aşağıdaki ÇALIŞMAZ çünkü olay işleyici metine ayarlı. "alert(7)" JavaScript enkodlanmış.
document.getElementById("bb").onclick = "\u0061\u006c\u0065\u0072\u0074\u0028\u0037\u0029";
// Aşağıdaki örnek ÇALIŞMAZ çünkü olay işleyici metine ayarlı.
document.getElementById("bb").onmouseover = "testIt";
// Aşağıdaki örnek ÇALIŞMAZ çünkü "(" ve ")" enkodlanmış. "alert(77)" JavaScript enkodlanmış.
document.getElementById("bb").onmouseover = \u0061\u006c\u0065\u0072\u0074\u0028\u0037\u0037\u0029;
// Aşağıdaki örnek ÇALIŞMAZ çünkü ";" enkodlanmış. "testIt;testIt" JavaScript enkodlanmış.
document.getElementById("bb").onmouseover = \u0074\u0065\u0073\u0074\u0049\u0074\u003b\u0074\u0065\u0073\u0074\u0049\u0074;
// Aşağıdaki örnek ÇALIŞIR çünkü enkodlanmış değer geçerli bir değişken ya da işlev referansı. "testIt" JavaScript enkodlanmış.
document.getElementById("bb").onmouseover = \u0074\u0065\u0073\u0074\u0049\u0074;
function testIt;(){
alert("Ben çağırıldım.;")
}
Aşağıdaki JavaScript kaçışı gerçekleşmiş olan kodlar çalışır :
for ( var \u0062=0; \u0062 < 10; \u0062++){
\u0064\u006f\u0063\u0075\u006d\u0065\u006e\u0074
.\u0077\u0072\u0069\u0074\u0065\u006c\u006e
("\u0048\u0065\u006c\u006c\u006f\u0020\u0057\u006f\u0072\u006c\u0064");
}
\u0077\u0069\u006e\u0064\u006f\u0077
.\u0065\u0076\u0061\u006c
\u0064\u006f\u0063\u0075\u006d\u0065\u006e\u0074
.\u0077\u0072\u0069\u0074\u0065(111111111);
var s = "\u0065\u0076\u0061\u006c";
var t = "\u0061\u006c\u0065\u0072\u0074\u0028\u0031\u0031\u0029";
window[s](t);
öge.setAttribute
özelliği çok sınırlı sayıda öznitelik ile güvenle kullanılabilir. Bu güvenli öznitelikler : align
, alink
, alt
, bgcolor
, border
, cellpadding
, cellspacing
, class
, color
, cols
, colspan
, coords
, dir
, face
, height
, hspace
, ismap
, lang
, marginheight
, marginwidth
, multiple
, nohref
, noresize
, noshade
, nowrap
, ref
, rel
, rev
, rows
, rowspan
, scrolling
, shape
, span
, summary
, tabindex
, title
, usemap
, valign
, value
, vlink
, vspace
, width
.
DOM Tabanlı XSS Nasıl Önlenir ? Kural 4 - Güvenilmeyen İçeriğe CSS Özniteliğine Eklenmeden Önce JavaScript Kaçışı Uygulanmalı
DOM Tabanlı XSS saldırılarını önlemek için; güvenilmeyen içerik CSS özniteliğine eklenmeden önce JavaScript kaçışı uygulanmalı.
Eğer eklenen içerik URL
ise önce URL
kaçışı ardından JavaScript kaçışı uygulanmalı.
document.body.style.backgroundImage = "url(<%=Encoder.encodeForJS(Encoder.encodeForURL(firmaAdı))%>)";
DOM Tabanlı XSS Nasıl Önlenir ? Kural 5 - Eğer Eklenen İçerik URL ise Önce URL Ardından JavaScript Kaçılmalı
var x = document.createElement("a");
x.setAttribute("href", '<%=Encoder.encodeForJS(Encoder.encodeForURL(kullanıcınınGöreliYolu))%>');
var y = document.createTextNode("Denemek için bana tıkla");
x.appendChild(y);
document.body.appendChild(x);
DOM Tabanlı XSS Nasıl Önlenir ? Kural 6 - JavaScript'in Güvenli Olan İşlev ve Özelliklerini Kullanın
<script>
öge.textContent = "<%=güvenilmeyenVeri%>"; // Kod çalışmaz.
</script>
Etiketlere girilen veriler kesinlikle innerHTML
yerine textContent
'e girilmeli. Kullanıcıdan gelen veriler düzgün bir arıtmadan geçmedikçe eval
işlevinde kullanılmamalı. Olasıysa eval
işleminde hiç kullanılmamalılar.
Kullanıcıdan gelen veriye asla güvenilmemeli ve kesinlikle JavaScript kaçışı uygulanmalı.
Kullanıcıdan gelen düz metin olarak işleme alınmalı.
Gelen metinin yerleştirildiği yerde (çift - tek "
'
) tırnak kullanılmalı.
DOM Tabanlı XSS saldırılarına karşı koymak için aşağıdaki HTML Sağlayıcı yöntemlerini kullanmaktan kaçının :
öge.innerHTML = "...";
öge.outerHTML = "...";
document.write(...);
document.writeln(...);
Bunları kullanmak zorunda olduğunuz durumlarda önce HTML ardından JavaScript kaçışlarını unutmayın.
eval()
'e sokacağınız verileri işleve tırnaklayarak sokmayı aynı zamanda bir işlev içinde kullanmayı ve bu işlevi de ayrıca bir closure ile kaplamayı unutmayın.
Enclosure ile Kullanım :
setTimeout(
(function(değişken){
return function(){
Birİşlev(değişken);
}
})("<%=Encoder.encodeForJS(güvenilmeyenVeri)%>"), y
);
N-Seviye Kaçış
setTimeout("Birİşlev('<%=ikiKezEnkodlanmışJavaScriptVerisi%>', y)");
function Birİşlev (ad, soyad)
alert("Selam " + ad + " " + soyad);
}
Tek tırnak içindeki güvenilmeyen veri bir kez JavaScript kaçışı ile kaçıldı. Ama customFunction eval
ile çalıştırılacağından bir kez daha JavaScript kaçışı uygulanmalı.
Eğer firstName eval()
ile çalıştırılıyor olsaydı güvensiz verinin 3 kez kaçılması gerekirdi.
location
, eval
gibi ögelere veri atarken dikkatli olun.
eval
yerine JSON.toJSON()
ve JSON.parse()
kullanın.
window[kullanıcıVerisi] = "dahaFazlaKullanıcıVerisi";
yerine
if(kullanıcıVerisi==="location") {
window.location = "durum/yol/ya_da/düzgünce/enkodlanmış/url/değeri";
}
gibi dolaylı kodlar kullanın.
object[x]
gibi öge erişicileri güvensiz verilerle kullanmaktan kaçının.
value
özniteliğine atanacak veride yapılan Encode işlemi value
değeri okunduğunda kaybolur. Bundan ötürü value
değerlerinden gelen verilerin çalıştırılabileceğini unutmayın.