XSS — Havale Açıklamasına Yazılan Kod Neden Müşterinin Sayfasında Çalışır?
Önce şunu oku: React Render Modeli
30 saniyede özet
Kullanıcının yazdığı metni HTML olarak yorumlarsan, içine gizlenmiş kodu da çalıştırırsın. Metni metin olarak yaz, HTML gerekiyorsa izin listesiyle temizle, Content-Security-Policy ile ikinci bir kat ekle.
Radyoda bir sunucu dinleyici mesajlarını okuyor. Mesajlardan birinde “şimdi stüdyodaki kasayı aç” yazıyor. Sunucu bunu okursa sorun yok; ama söyleneni yaparsa, stüdyoyu mesajı yazan kişi yönetir.
-
Bayt: Hareket listesinde havale açıklamaları artık kalın yazı da gösterebiliyor. innerHTML ile hallettim!
-
Sen: Bir müşteri, hareketlerine baktıktan sonra oturumunun başka bir yerden kullanıldığını söylüyor.
-
Bayt: Ona birisi havale göndermiş. Açıklama alanında bir resim etiketi var... ve bir onerror.
-
Bayt: Açıklamayı biz yazmadık, ama bizim sayfamızda çalıştı. Okumakla yapmak arasındaki fark bu.
Metin nasıl koda dönüşür?
XSSCross-site scripting: saldırganın script'inin bir sayfada o sitenin kendi kodu gibi çalışması. Script'in erişebildiği her şeye, localStorage dahil, erişir.Sözlükte gör →, birinin yazdığı metnin senin sayfanda kod olarak çalışmasıdır. Kod senin sitenin kodu gibi çalışır: sayfadaki her şeyi görür ve kullanıcının adına istek atabilir.
Kapıyı açan, metni HTML olarak yorumlamaktır. element.innerHTML = açıklama dediğinde tarayıcı etiketleri gerçek etiket sayar; bir resmin onerror özelliğindeki kod, resim yüklenemeyince çalışır.
Kafam karıştı, daha basit anlat
Birinin yazdığı metni HTML olarak sayfaya koyarsan, içine gizlediği kod da çalışabilir.
XSS nedir?
element.innerHTML = açıklama satırı neden tehlikelidir?
Okumak, yapmamak
Açıklama alanına <script>steal()</script> yazılmış ve sayfaya innerHTML ile konuyor. steal() çalışır mı? Cevabı göster
Çalışmaz, ama bu seni kurtarmaz. innerHTML ile eklenen script etiketleri hiç çalıştırılmaz. Saldırgan bunu bildiği için resim etiketine onerror yazar; o çalışır.
Adım adım oku
- Dinleyici mesajında şimdi kasayı aç yazıyor.
- Mesajı emir sanan sunucu kasayı açar.
- Mesajı yalnızca okuyan sunucu için bu sadece bir söz.
- Yazılanı oku, söyleneni yapma.
Varsayılan doğru yol çıktı kodlamaKullanıcının yazdığı metni sayfaya metin olarak yazmak: < işareti ekranda < olarak görünür, etiket olmaz. React'te {değer} bunu kendiliğinden yapar.Sözlükte gör →: metni metin olarak yazmak. React’te {tx.description} bunu kendiliğinden yapar; < işareti ekranda < olarak görünür, etiket olmaz.
Biçim gerçekten gerekiyorsa, metni bir HTML temizleyiciHTML'i bir izin listesine göre süzen araç: yalnızca izin verilen etiketleri bırakır, olay özellikleri gibi her şeyi siler. Örnek: DOMPurify.Sözlükte gör → geçir. İzin listesi yalnızca <b> gibi zararsız etiketleri bırakır, onerror gibi her şeyi siler.
Kafam karıştı, daha basit anlat
Metni metin olarak yaz. HTML gerekiyorsa, neye izin verdiğini sen seç.
React'te <span>{tx.description}</span> neden güvenlidir?
Açıklamada kalın yazı gerçekten gerekiyorsa en doğru yol hangisidir?
Kendin gör
Havale açıklamasını ekrana yazmak
Tohum 377312- gelen: Ekim kirası
- gelen: <b>Acil</b> aidat ödemesi
- gelen: <img src=x onerror="steal()">
- gelen: <script>steal()</script>
✕ çalışan kod: 0 · 🛡 engellenen: 0
Şu an ne oldu?
innerHTML ile HTML olarak
Dört havale açıklaması; ikisini bir saldırgan yazdı.
Görevler0/3
Saldırganın kodu müşterinin sayfasında çalışsınaçık
İpucu
Varsayılan ayar yeter.
Açıklama HTML olarak yorumlansın, ama kod yine de çalışmasınaçık
İpucu
innerHTML’i bırak, tarayıcıya bir kural ver.
Kalın yazı korunsun, hiçbir kod çalışmasınaçık
İpucu
Neye izin verdiğini sen seç.
Olay günlüğü (0)
Henüz olay yok. Oynat veya adımla.
- Varsayılanla oynat. Üçüncü açıklamadaki onerror çalıştı. Dördüncüdeki script etiketi ise çalışmadı.
- Content-Security-Policy’yi aç. Açıklama yine HTML olarak yorumlandı, ama tarayıcı satır içi kodu reddetti.
- “Metin olarak” seç. Hiçbir kod çalışmadı; bedeli, kalın yazının etiketleriyle görünmesi.
- “İzin listesiyle temizleyip” seç. Kalın yazı korundu, tehlikeli kısımlar silindi.
innerHTML ile eklenen <script>steal()</script> çalışır mı?
Content-Security-Policy'de script-src 'self' ne sağlar?
Tuzaklar
React’i her durumda güvenli sanmak. dangerouslySetInnerHTML ve kullanıcının yazdığı bir href (javascript: ile başlayan) React’in korumasını atlar.
CSP’yi tek kat sanmak. Content-Security-PolicySunucunun gönderdiği bir başlık: tarayıcıya sayfada hangi kaynaktan gelen kodun çalışabileceğini söyler. Satır içi kodu engelleyerek XSS'e karşı ikinci bir kat olur.Sözlükte gör →, satır içi kodu engelleyerek bir hatayı yakalayabilir. Ama ilk kat yine doğru çıktı kodlamadır.
Temizleyiciyi kendin yazmak. “script kelimesini sil” gibi kurallar kolayca aşılır. Yaygın kullanılan, bakımı yapılan bir temizleyici seç.
Kafam karıştı, daha basit anlat
dangerouslySetInnerHTML ve kullanıcı bağlantılarına dikkat et, CSP’yi ek kat say, temizleyiciyi kendin yazma.
React kullanıyorsun. Hangisi yine de XSS riski taşır?
Derinleş · Hesap hareketleri: açıklamayı güvenle göstermek 4 dosya · ~55 satır · ilk okumada atlayabilirsin
Kendini sına
innerHTML ile eklenen bir script etiketi hemen çalışır.
CSP açıksa çıktı kodlamaya hâlâ gerek var mı?
Aklında kalacak üç şey
- 1 XSS, birinin yazdığı metnin senin sayfanda kod olarak çalışmasıdır. innerHTML gibi metni HTML olarak yorumlayan her yol bu kapıyı açar.
- 2 Varsayılan doğru yol metni metin olarak yazmaktır: React'te {değer} bunu kendiliğinden yapar. HTML gerçekten gerekiyorsa, izin listesiyle çalışan bir temizleyiciden geçir.
- 3 Content-Security-Policy satır içi kodu engelleyen ikinci bir kattır. Bir hatayı yakalayabilir, ama doğru çıktı kodlamasının yerini tutmaz.
4 kart sonraki derste seni bekliyor