Konuyu Okuyanlar:

XSS Nedir? Reflected, Stored ve DOM Tabanlı XSS (DVWA Lab ile Uygulamalı)

XSS Nedir? Reflected, Stored ve DOM Tabanlı XSS (DVWA Lab ile Uygulamalı)
[center]
[Resim: attachment.php?aid=126]
[/center]

Selam millet, BlueTornado burada.

Cross-Site Scripting (XSS), web uygulamalarında en sık karşılaşılan enjeksiyon zafiyetlerinden biridir. Bu konuda XSS'in ne olduğunu, üç ana tipini (Reflected, Stored, DOM), DVWA labında nasıl güvenli şekilde gözlemleyeceğinizi ve korunma yöntemlerini adım adım anlatacağım. Amaç saldırı senaryosu ezberletmek değil; neden oluştuğunu ve nasıl engellendiğini anlamanız.

Konuda Anlatılacaklar
  1. XSS nedir, ne değildir?
  2. DVWA lab kurulumu ve güvenlik seviyeleri
  3. Reflected XSS: istekte yansıyan girdi
  4. Stored XSS: kalıcı depolanan girdi
  5. DOM-based XSS: tarayıcı tarafı
  6. Çıktı encoding, CSP ve framework korumaları
  7. İleri seviye: mutasyon XSS, cookie bayrakları, raporlama
  8. Kaynakça ve yasal uyarı

1) XSS Nedir?
XSS, uygulamanın kullanıcıdan gelen veriyi, tarayıcının JavaScript olarak yorumlayabileceği biçimde doğrulamadan veya encode etmeden HTML/JS bağlamına yazmasıdır. Sonuçta saldırgan, kurbanın tarayıcısında kendi script'ini çalıştırabilir.

XSS ile yapılabilecekler (eğitim bağlamında riskleri anlamak için):
  • Oturum çerezinin (HttpOnly değilse) okunması
  • Sayfa içeriğinin değiştirilmesi (defacement / phishing formu)
  • Kurban adına istek atılması (aynı origin içinde)
  • Keylogger benzeri script enjekte edilmesi

XSS bir "sunucuyu ele geçirme" zafiyeti değildir; kullanıcının tarayıcısını hedefler. Yine de admin paneline Stored XSS düşerse etki çok yüksek olabilir.

Alıntı:OWASP Top 10 2021'de XSS, A03 Injection kategorisi altında değerlendirilir. Ayrı bir Top 10 maddesi olarak listelenmese de pratikte en sık bulgulardan biridir.

2) Lab: DVWA Kurulumu
Yalnızca kendi bilgisayarınızda, izole ortamda çalıştırın.

Kod:
git clone https://github.com/digininja/DVWA.git cd DVWA docker compose up -d

Tarayıcı:
Kod:
http://127.0.0.1
(compose port eşlemenize göre değişebilir). Varsayılan giriş bilgileri DVWA dokümantasyonunda yer alır; ilk girişte Setup sayfasından veritabanını oluşturun.

Kod:
# Güvenlik seviyesini ayarlamak için DVWA menüsü: # DVWA Security -> Low / Medium / High / Impossible

Bu konuda önce Low, sonra Impossible seviyesini karşılaştıracağız. Impossible, korunmuş referans implementasyondur.

[center][/center]

3) Kavram Referansı

Context (bağlam): Girdinin HTML gövdesine mi, attribute içine mi, JavaScript string'ine mi, URL'ye mi yazıldığı kritiktir. Encoding stratejisi bağlama göre değişir.

Kod:
# HTML gövde bağlamı (kavramsal tehlikeli) echo "<p>Merhaba $name</p>" # Attribute bağlamı echo "<input value='$name'>"

Output encoding: Gösterilecek verinin HTML entity'ye çevrilmesi (
Kod:
<
->
Kod:
&lt;
gibi).

CSP (Content Security Policy): Tarayıcıya hangi script kaynaklarının çalışabileceğini söyleyen HTTP başlığı. XSS'i tamamen bitirmez ama etkisini ciddi azaltır.

Kod:
# Örnek CSP (sıkılaştırılmış, kavramsal) Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'

HttpOnly / Secure / SameSite çerez bayrakları:
Kod:
Set-Cookie: session=...; HttpOnly; Secure; SameSite=Lax
HttpOnly, document.cookie ile çerezin JS'ten okunmasını engeller (XSS'in oturum çalma etkisini azaltır; XSS'i yok etmez).

4) Reflected XSS (DVWA Low)
Reflected XSS'te zararlı girdi genellikle URL parametresi veya form alanı olarak gelir, sunucu cevabında hemen yansır ve depolanmaz. Kurbanın özel hazırlanmış bir linke tıklaması gerekir.

DVWA'da XSS (Reflected) sayfasına gidin, güvenlik seviyesini Low yapın.

Kod:
# Labda denenebilecek basit payload (yalnızca DVWA) <script>alert(1)</script>

Forma yazıp gönderdiğinizde alert çıkıyorsa, girdi encode edilmeden HTML'e basılıyor demektir. Bu, "XSS var" kanıtı için klasik bir smoke test'tir; gerçek bir pentest raporunda daha anlamlı bir PoC (ör. çerez bayrağı kontrolü, DOM değişikliği) tercih edilir.

[center][/center]

Çıktıyı yorumlama:
  • Alert çıktı -> girdi script olarak yorumlandı
  • Sayfada
    Kod:
    &lt;script&gt;
    görünüyorsa encoding çalışıyor olabilir
  • WAF/filtre sadece
    Kod:
    <script>
    kelimesini kesiyorsa başka etiketlerle bypass denenir; labda High seviyeye geçmeden önce filtre mantığını anlayın

Medium seviyede çoğu DVWA kurulumunda
Kod:
<script>
kelimesi strip edilir. Bu, güvenli encoding değildir; kara liste (blacklist) yaklaşımıdır ve kırılgandır.

Kod:
# Kara listenin zayıflığı (kavramsal örnekler, lab) <img src=x onerror=alert(1)> <svg onload=alert(1)>

Impossible seviyesinde htmlspecialchars benzeri doğru encoding kullanılır; payload metin olarak görünür, çalışmaz.

5) Stored XSS (DVWA)
Stored (persistent) XSS'te girdi veritabanına veya başka kalıcı depoya yazılır ve her ziyaretçinin sayfasında tekrar gösterilir. Guestbook, yorum, profil bio alanları tipik hedeflerdir.

DVWA XSS (Stored) sayfasında Low seviyede name/message alanlarına payload bırakın:

Kod:
<script>alert('stored')</script>

Sayfayı yenilediğinizde veya başka bir tarayıcı profiliyle girdiğinizde alert tekrarlanıyorsa Stored XSS söz konusudur. Etki yüzeyi Reflected'dan genelde daha yüksektir çünkü tek bir kurban linki gerekmez.

[center][/center]

Savunma gözlemi: Impossible seviyeye alıp aynı payload'ı deneyin. Veri saklansa bile gösterilirken encode edilmelidir. "Saklarken temizle, gösterirken encode et" ikilisinden özellikle gösterirken encode vazgeçilmezdir; çünkü veri birden fazla bağlamda kullanılabilir.

6) DOM-Based XSS
DOM XSS'te sunucu cevabı "temiz" görünebilir; zafiyet tarayıcıdaki JavaScript'in
Kod:
location
,
Kod:
hash
,
Kod:
document.referrer
gibi kaynaklardan okuduğu veriyi
Kod:
innerHTML
,
Kod:
document.write
,
Kod:
eval
gibi güvenli olmayan sink'lere yazmasından doğar.

Kod:
// Tehlikeli kalıp (kavramsal) var q = location.hash.substring(1); document.getElementById('out').innerHTML = q; // Daha güvenli: textContent kullanmak document.getElementById('out').textContent = q;

DVWA'da DOM XSS için ayrı sayfa/versiyon farklılıkları olabilir; Juice Shop challenge'larında da DOM XSS örnekleri bulunur. Kaynak (source) ve sink listeleri için OWASP DOM based XSS Prevention Cheat Sheet'e bakın.

Kod:
# Kaynak örnekleri: location, document.URL, postMessage # Sink örnekleri: innerHTML, outerHTML, eval, setTimeout(string)

7) Uygulamalı: Filtreyi Anlamak (Adım Adım)
Low -> Medium -> High ilerleyin; her seviyede şu notları alın:

Kod:
# Not şablonu Seviye: Medium Denenen: <script>alert(1)</script> Sonuç: script kelimesi silindi / sayfa boş / encode edildi Çıkarım: blacklist mi, encoding mi?

Kod:
# High seviyede sık görülen: gelişmiş filtre veya kısmi encoding # Impossible: doğru kütüphane encoding + katı kurallar

Burp Suite kullanıyorsanız Proxy ile isteği yakalayıp parametreyi Repeater'da değiştirerek sunucu cevabında girdinin nereye yazıldığını izleyin (yalnızca lab).

[center][/center]

8) Korunma: Geliştirici Kontrol Listesi
  • Şablon motorunun otomatik escaping özelliğini kapatmayın (Django, Jinja2 autoescape, React JSX varsayılanı)
  • Kod:
    dangerouslySetInnerHTML
    ,
    Kod:
    |safe
    ,
    Kod:
    v-html
    gibi kaçış kapılarını kod incelemesinde işaretleyin
  • Bağlama uygun encoding kullanın (HTML, attribute, JS, URL, CSS ayrıdır)
  • Zengin metin (WYSIWYG) gerekiyorsa sıkı HTML sanitizer (ör. DOMPurify) kullanın
  • CSP ekleyin; inline script'i azaltın
  • Çerezlerde HttpOnly; Secure; SameSite ayarlayın
  • WAF kara listesine güvenerek "XSS bitti" demeyin

Kod:
# Python / Jinja2 (otomatik escape açıkken) {{ user_comment }} # Bilerek ham HTML (kaçının veya sanitize edin) {{ user_comment | safe }}

Kod:
# PHP örneği (bağlama göre) echo htmlspecialchars($name, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');

9) İleri Seviye Notlar
Mutation XSS (mXSS): Tarayıcının HTML parser'ının beklenmedik şekilde DOM'u "düzeltmesi" sonucu sanitizer'ların bypass edilmesi. Kendi sanitizer'ınızı yazmak yerine bakımı yapılan kütüphaneleri kullanın.

Blind XSS: Payload'un admin panelinde, log görüntüleyicide veya destek aracında sonradan tetiklenmesi. BeAlert / XSS Hunter benzeri geri çağırma (callback) servisleri pentestlerde kullanılır; izinsiz sistemlerde asla.

Raporlama dili:
Kod:
Bulgu: Stored XSS (CWE-79) Konum: /guestbook message alanı Etki: Oturum çerezi HttpOnly değilse hesap ele geçirme riski Kanıt: Lab ortamında alert PoC + HTML kaynak çıktısı Öneri: Çıktı encoding + CSP + HttpOnly

[center][/center]

10) Sonuç
XSS; Reflected, Stored ve DOM olarak üç ana ailede incelenir. Ortak kök neden, güvensiz bağlama yazımdır. DVWA Low'da zafiyeti görün, Impossible'da doğru kodu inceleyin, kendi uygulamanızda escaping + CSP + çerez bayraklarını kontrol edin.

Kaynakça
Yasal Uyarı
Bu içerik eğitim ve savunma amaçlıdır. XSS testleri yalnızca kendi labınızda veya yazılı yetki verilen sistemlerde yapılmalıdır. İzinsiz testler TCK 243-245 kapsamında suç oluşturabilir. Sorumluluk uygulayana aittir.


Ek DosyalarEkran Görüntüleri
   
Cevapla



Hızlı Menü: