Reflected, Stored ve DOM-based…
Web güvenliğinde, yıllardır popülerliğini yitirmeyen ve OWASP Top 10 listesinin müdavimi olan bir zafiyet var: Cross-Site Scripting, yani bilinen adıyla XSS. Bu yazıda, XSS'in ne olduğunu, saldırganların bunu nasıl kullandığını ve geliştiricilerin uygulamalarını nasıl savunabileceğini inceleyeceğiz.
XSS Nedir ve Neden Tehlikelidir?
Cross-Site Scripting (XSS), bir saldırganın, kullanıcıların etkileşimde bulunduğu bir web uygulamasına zararlı kodlar (genellikle JavaScript) enjekte etmesine olanak tanıyan bir güvenlik zafiyetidir.
Normal şartlarda tarayıcılar, Same Origin Policy (SOP) adı verilen bir mekanizma ile siteleri birbirinden izole eder. Ancak XSS, saldırganın bu politikayı atlatmasına izin verir.
Bir saldırgan XSS zafiyetini sömürdüğünde şunları yapabilir:
- Kurbanın oturumunu ele geçirebilir (Session Hijacking).
- Kullanıcı adına izinsiz işlemler yapabilir.
- Kullanıcının görebildiği tüm hassas verilere erişebilir.
- Kullanıcının klavye vuruşlarını veya parolalarını çalabilir.
XSS Saldırı Türleri
XSS zafiyetleri temel olarak üç ana kategoriye ayrılır. Her birinin çalışma mantığı farklıdır ancak sonucu aynıdır: Zararlı kodun kurbanda çalışması.
1. Reflected XSS (Yansıyan XSS)
En sık karşılaşılan ve tespiti nispeten daha kolay olan türdür. Saldırganın zararlı kodu, kurbana gönderilen bir HTTP isteğinin (genellikle URL parametreleri) içinde yer alır ve sunucu bu kodu hiçbir temizleme yapmadan anında yanıt olarak geri döndürür.
Senaryo: Bir arama çubuğu düşünün.
- URL:
https://guvensiz-site.com/search?term=hediye - Yanıt:
<p>Aranan kelime: hediye</p>
Saldırgan URL'i şu şekilde değiştirirse: https://guvensiz-site.com/search?term=<script>alert(1)</script>
Sunucu yanıtı şu olur: <p>Aranan kelime: <script>alert(1)</script></p>
Kurban bu linke tıkladığında tarayıcı scripti çalıştırır.
2. Stored XSS (Depolanan/Kalıcı XSS)
Bu tür, Reflected XSS'e göre çok daha tehlikelidir çünkü saldırı kalıcıdır. Saldırgan zararlı kodu web sitesinin veritabanına kaydeder (örneğin bir blog yorumu, forum mesajı veya profil bilgisi olarak).
Daha sonra bu sayfayı ziyaret eden herkes, veritabanından çekilen bu zararlı kodu tarayıcısında çalıştırır. Saldırganın kurbanı özel bir linke tıklatmaya ikna etmesine gerek yoktur; sadece sayfayı ziyaret etmeleri yeterlidir.
3. DOM-based XSS
Burada zafiyet sunucu tarafında değil, tamamen istemci tarafındaki (client-side) JavaScript kodlarındadır. Sayfa yüklendikten sonra, JavaScript'in kullanıcı girdisini (source) alıp güvensiz bir şekilde HTML'e işlemesiyle (sink) oluşur.
- Source (Kaynak):
location.search,document.referrergibi saldırganın manipüle edebileceği girdiler. - Sink (Hedef):
innerHTML,document.write,eval()gibi kod çalıştıran fonksiyonlar.
Örnek zafiyetli kod:
var search = document.getElementById('search').value;
var results = document.getElementById('results');
results.innerHTML = 'Sonuç: ' + search; // Zafiyet buradaXSS ile Neler Yapılabilir? (Exploitation)
Birçok kişi XSS'i sadece ekranda alert(1) penceresi açmak zanneder. Ancak alert(), sadece bir "Proof of Concept" (Kavram Kanıtı) aracıdır. Gerçek dünyada saldırganlar çok daha fazlasını hedefler:
- Çerez Çalma (Cookie Stealing):
document.cookiekomutu ile kurbanın oturum bilgilerini çalıp, kendi sunucularına gönderebilirler. AncakHttpOnlybayrağı varsa bu yöntem engellenebilir. - Parola Yakalama: Günümüzde tarayıcıların "Otomatik Doldur" (Autofill) özelliği yaygındır. Saldırgan sayfaya sahte bir giriş formu enjekte edip tarayıcının burayı doldurmasını sağlayarak parolayı çalabilir.
- CSRF Korumasını Aşma: XSS, sitenin CSRF tokenlarını okuyabildiği için, normalde CSRF koruması olan işlemleri (örneğin e-posta değiştirme) saldırganın yapabilmesine olanak tanır.
XSS Zafiyetlerini Nasıl Tespit Ederiz?
XSS zafiyetlerini bulmak için Burp Suite gibi araçlar endüstri standardıdır.
- Manuel Test: Uygulamadaki her girdi noktasına (input fields, URL parametreleri) özel karakterler içeren basit bir string (örneğin:
halilxss) girilir. Daha sonra yanıt incelenerek bu string'in nerede ve nasıl yansıdığına bakılır. - Otomatik Tarama: Burp Scanner, statik ve dinamik analiz yaparak özellikle DOM XSS gibi tespiti zor açıkları bulmakta oldukça başarılıdır.
*** Chrome v92'den sonra
alert()fonksiyonu cross-origin iframe'lerde engellendi. Bu yüzden testlerinizdeprint()fonksiyonunu kullanmak daha garantili bir yöntem olabilir.
XSS'ten Korunma Yöntemleri (Prevention)
XSS'i engellemek tek bir satır kodla mümkün değildir, derinlemesine savunma (defense in depth) gerektirir.
1. Çıktı Kodlama (Output Encoding)
Kullanıcıdan gelen veriyi sayfaya yazdırırken, tarayıcının bunu kod olarak değil, metin olarak algılamasını sağlamalısınız.
- HTML Context için:
<yerine<,>yerine>kullanılmalı. - JavaScript Context için: Unicode kaçış karakterleri (
\u003c) kullanılmalı.
2. Girdi Doğrulama (Input Validation)
Kullanıcıdan gelen veri, beklendiği formatta mı? Örneğin yaş bilgisi isteniyorsa sadece tamsayı (integer) kabul edilmeli. Girdilerde "blacklist" (yasaklılar listesi) yerine "whitelist" (izin verilenler listesi) kullanmak her zaman daha güvenlidir.
3. Content Security Policy (CSP)
CSP, XSS'e karşı son savunma hattıdır. Sunucunun döndürdüğü bir HTTP başlığı (header) ile tarayıcıya hangi kaynakların (script, resim, stil) yüklenebileceği söylenir.
Örnek bir CSP başlığı: Content-Security-Policy: default-src 'self'; script-src 'self' https://guvenilir-scripts.com
Bu kural, sadece kendi domaininizden veya belirtilen güvenli domainden gelen scriptlerin çalışmasına izin verir. Bir saldırgan sayfaya script enjekte etse bile CSP bunu engelleyecektir.
Sonuç
XSS, web uygulamalarının en yaygın zafiyetlerinden biri olmaya devam ediyor. Geliştiriciler olarak, kullanıcıdan gelen her veriye "güvensiz" gözüyle bakmalı, doğru encoding yöntemlerini kullanmalı ve CSP gibi modern güvenlik önlemlerini uygulamalarımıza entegre etmeliyiz.
*Halil İbrahim Eroğlu*