Cross-Site Scripting (XSS) Nedir?
Cross-Site Scripting (XSS), web uygulamalarındaki en yaygın güvenlik açıklarından biridir. OWASP Top 10 listesinde sürekli olarak yer alan XSS, saldırganların web sayfalarına kötü amaçlı JavaScript kodu enjekte etmesine olanak tanır. Bu kod, kurbanın tarayıcısında çalışarak çerez çalma, oturum ele geçirme, kimlik avı ve hatta kötü amaçlı yazılım dağıtımı gibi saldırıları mümkün kılar.
2024 yılı verilerine göre XSS, tüm web güvenlik açıklarının yaklaşık %18'ini oluşturmaktadır. Bu oran, XSS'in hala en ciddi web güvenlik tehditlerinden biri olduğunu göstermektedir.
XSS Saldırı Türleri
1. Stored XSS (Kalıcı XSS)
Stored XSS, en tehlikeli XSS türüdür. Saldırgan, kötü amaçlı kodu doğrudan web uygulamasının veritabanında saklar. Bu kod, sayfayı ziyaret eden her kullanıcının tarayıcısında otomatik olarak çalıştırılır.
Stored XSS'in yaygın hedefleri:
- Blog yorumları ve forum gönderileri
- Kullanıcı profil bilgileri
- Ürün değerlendirmeleri
- Mesajlaşma sistemleri
- Destek talepleri
Stored XSS neden en tehlikelisidir?
- Saldırgan ile kurban arasında doğrudan etkileşim gerekmez
- Sayfayı ziyaret eden tüm kullanıcılar etkilenir
- Kötü amaçlı kod kalıcı olarak saklanır
- Tespit edilmesi zor olabilir
2. Reflected XSS (Yansıtılan XSS)
Reflected XSS'te kötü amaçlı kod, URL parametreleri, form girdileri veya HTTP başlıkları aracılığıyla sunucuya gönderilir ve sunucu yanıtında doğrudan yansıtılır. Saldırganın, kurbanı özel hazırlanmış bir bağlantıya tıklatması gerekir.
Reflected XSS saldırı vektörleri:
- Arama sonuç sayfaları
- Hata mesajları
- URL parametreleri
- Form alanları (sunucu tarafında yansıtılan)
- HTTP başlıkları
3. DOM-Based XSS
DOM XSS, sunucu tarafında hiçbir değişiklik yapılmadan tamamen istemci tarafında gerçekleşir. JavaScript kodu, DOM'u güvensiz bir şekilde manipüle ettiğinde ortaya çıkar. Sunucu loglarında iz bırakmadığı için tespit edilmesi en zor XSS türüdür.
DOM XSS'e yol açan tehlikeli JavaScript kaynakları (sources):
document.URLdocument.locationdocument.referrerwindow.namelocation.hash
Tehlikeli hedefler (sinks):
innerHTMLdocument.write()eval()setTimeout()/setInterval()element.setAttribute()(event handler'larla)
XSS Saldırı Türleri Karşılaştırması
| Özellik | Stored XSS | Reflected XSS | DOM XSS |
|---|---|---|---|
| Kötü amaçlı kod nerede? | Veritabanında | URL/istekte | İstemci tarafında |
| Sunucu etkileşimi | Evet | Evet | Hayır |
| Kurban etkileşimi | Sadece sayfa ziyareti | Bağlantıya tıklama | Bağlantıya tıklama |
| Etki alanı | Tüm ziyaretçiler | Tek kullanıcı | Tek kullanıcı |
| Tespit zorluğu | Orta | Kolay | Zor |
| Tehlike seviyesi | Çok Yüksek | Yüksek | Yüksek |
Input Sanitization (Girdi Temizleme)
Input sanitization, XSS'e karşı ilk savunma hattıdır. Kullanıcıdan gelen tüm girdiler potansiyel olarak tehlikeli kabul edilmelidir.
Sunucu Tarafında Doğrulama
- Beyaz liste yaklaşımı: İzin verilen karakterleri tanımlayın, diğerlerini reddedin
- Veri tipi doğrulama: Sayısal alanlar için yalnızca sayısal giriş kabul edin
- Uzunluk sınırlaması: Girdi uzunluğunu makul seviyede sınırlayın
- Regex doğrulama: E-posta, telefon gibi alanlar için format doğrulama
- HTML temizleme: DOMPurify, Bleach gibi kütüphaneler kullanarak tehlikeli etiketleri kaldırın
İstemci Tarafında Doğrulama
İstemci tarafı doğrulama kullanıcı deneyimini iyileştirir ancak güvenlik amacıyla asla yeterli değildir. Her zaman sunucu tarafında da doğrulama yapılmalıdır.
Güvenlik kuralı: Asla istemci tarafı doğrulamaya güvenmeyin. İstemci tarafı kontrolleri kolayca atlanabilir. Sunucu tarafı doğrulama her zaman birincil savunma hattı olmalıdır.
Output Encoding (Çıktı Kodlama)
Output encoding, kullanıcı girdilerini görüntülerken tehlikeli karakterleri güvenli eşdeğerleriyle değiştirmektir. Bağlama göre doğru encoding yöntemi seçilmelidir:
HTML Encoding
HTML bağlamında kullanıcı verilerini görüntülerken HTML entity encoding uygulanmalıdır:
<karakteri<olarak kodlanır>karakteri>olarak kodlanır&karakteri&olarak kodlanır"karakteri"olarak kodlanır'karakteri'olarak kodlanır
JavaScript Encoding
JavaScript bağlamında kullanıcı verileri kullanılırken JavaScript encoding uygulanmalıdır. JSON.stringify() fonksiyonu bu amaçla kullanılabilir, ancak yalnızca JSON veri yapısı içinde güvenlidir.
URL Encoding
URL parametrelerinde kullanıcı verileri yer aldığında URL encoding (percent-encoding) uygulanmalıdır. encodeURIComponent() fonksiyonu bu amaç için kullanılabilir.
CSS Encoding
CSS bağlamında kullanıcı verilerinin kullanılmasından mümkün olduğunca kaçınılmalıdır. Gerekli durumlarda CSS encoding uygulanmalıdır.
Content Security Policy (CSP)
Content Security Policy, XSS'e karşı en güçlü savunma mekanizmalarından biridir. CSP, tarayıcıya hangi kaynakların yüklenebileceğini bildiren bir HTTP başlığıdır.
CSP Direktifleri
| Direktif | Açıklama | Örnek |
|---|---|---|
| default-src | Varsayılan kaynak politikası | 'self' |
| script-src | JavaScript kaynak kısıtlaması | 'self' 'nonce-abc123' |
| style-src | CSS kaynak kısıtlaması | 'self' 'unsafe-inline' |
| img-src | Görsel kaynak kısıtlaması | 'self' data: https: |
| connect-src | AJAX/WebSocket kısıtlaması | 'self' api.example.com |
| frame-src | iframe kaynak kısıtlaması | 'none' |
| object-src | Plugin kaynak kısıtlaması | 'none' |
CSP Nonce ve Hash
Inline script'lerin çalışmasına izin vermek için nonce veya hash yaklaşımı kullanılır:
- Nonce: Her sayfa yüklemesinde benzersiz rastgele bir değer oluşturulur ve hem CSP başlığına hem de script etiketine eklenir
- Hash: İzin verilen inline script'in hash'i CSP başlığında belirtilir
CSP Raporlama
CSP ihlallerini izlemek için report-uri veya report-to direktiflerini kullanabilirsiniz. İlk aşamada Content-Security-Policy-Report-Only başlığını kullanarak politikayı enforcing yapmadan test edebilirsiniz.
Ek Güvenlik Başlıkları
CSP dışında XSS'e karşı koruma sağlayan ek HTTP güvenlik başlıkları:
- X-Content-Type-Options: nosniff — MIME type sniffing'i engeller
- X-Frame-Options: DENY — Clickjacking saldırılarını önler
- Referrer-Policy: strict-origin-when-cross-origin — Referrer bilgi sızıntısını sınırlar
- Permissions-Policy — Tarayıcı özelliklerine erişimi kısıtlar
- Strict-Transport-Security — HTTPS kullanımını zorunlu kılar
Framework'lere Özel Korumalar
React
React, JSX'te varsayılan olarak output encoding uygular. Ancak dangerouslySetInnerHTML kullanımında dikkatli olunmalıdır. Bu prop, HTML'i doğrudan DOM'a enjekte eder ve XSS riskine yol açabilir.
Angular
Angular, varsayılan olarak tüm değerleri güvensiz kabul eder ve otomatik sanitization uygular. bypassSecurityTrustHtml() gibi fonksiyonlar kullanılırken çok dikkatli olunmalıdır.
ASP.NET Core
ASP.NET Core, Razor view'larda varsayılan olarak HTML encoding uygular. @Html.Raw() kullanımı XSS riski oluşturur ve mümkün olduğunca kaçınılmalıdır.
XSS Test Araçları
- Burp Suite: Kapsamlı web güvenlik tarama aracı
- OWASP ZAP: Ücretsiz ve açık kaynaklı güvenlik tarayıcısı
- XSS Hunter: Blind XSS tespiti için özel araç
- DOM Invader: Burp Suite'in DOM XSS test modülü
- CSP Evaluator: Google'ın CSP politikası değerlendirme aracı
Güvenlik testlerini yalnızca kendi uygulamalarınızda ve yasal izinle gerçekleştirin. İzinsiz güvenlik testi yasal sonuçlar doğurabilir.
XSS Önleme Kontrol Listesi
- Tüm kullanıcı girdilerini sunucu tarafında doğrulayın
- Bağlama uygun output encoding uygulayın
- Sıkı bir Content Security Policy yapılandırın
- HttpOnly ve Secure çerez bayraklarını kullanın
- Framework'ünüzün yerleşik korumalarını devre dışı bırakmayın
- Güvenlik başlıklarını yapılandırın
- Düzenli güvenlik taramaları yapın
- Bağımlılıklarınızı güncel tutun
- Güvenlik eğitimi ve farkındalık programları uygulayın
- Güvenlik olayı müdahale planı oluşturun
Sonuç
XSS saldırılarından korunmak, tek bir önlemle değil, katmanlı bir güvenlik yaklaşımıyla mümkündür. Input sanitization, output encoding, Content Security Policy ve güvenlik başlıkları birlikte kullanıldığında etkili bir savunma oluşturur. Framework'ünüzün yerleşik korumalarını aktif tutun, düzenli güvenlik taramaları yapın ve ekibinizi güvenli kodlama pratikleri konusunda eğitin. Unutmayın, güvenlik sürekli bir süreçtir ve tehditlerin evrimine paralel olarak savunma stratejilerinizi de sürekli güncellemelisiniz.