XSS saldırısı, bir web uygulamasında saldırganın zararlı JavaScript kodunu başka bir kullanıcının tarayıcısında çalıştırmasına olanak tanıyan tehlikeli bir güvenlik açığıdır. Stored, Reflected ve DOM XSS türlerinin nasıl işlediği, etkileri ve sitenizi bu saldırılardan korumanın en etkili yolları detaylı şekilde açıklanıyor. Hem kullanıcılar hem de site sahipleri için XSS'in neden ciddi bir tehdit oluşturduğunu öğrenin.
XSS saldırısı, bir web uygulamasında saldırganın kendi JavaScript kodunu başka bir kullanıcının tarayıcısında çalıştırmasına olanak tanıyan bir güvenlik açığıdır. Site sunucusu düzgün şekilde çalışmaya devam edebilir; sorun, uygulamanın verileri yanlış işlemesinden ve tarayıcının bu verileri sayfanın bir parçası ya da çalıştırılabilir kod olarak kabul etmesine izin vermesinden kaynaklanır.
XSS yoluyla site içeriği değiştirilebilir, sahte formlar gösterilebilir, kullanıcı adına işlemler yapılabilir ve sayfanın erişebildiği bazı bilgilere ulaşılabilir. Bu saldırının tehlikesi, zararlı kodun gerçek site içinde çalışması ve mevcut sayfanın JavaScript'inin sahip olduğu tüm ayrıcalıklara sahip olmasındadır.
Cross Site Scripting (XSS) veya siteler arası komut dosyası, bir kullanıcıdan gelen güvenilmeyen verinin düzgün şekilde filtrelenmeden veya güvenli biçimde işlenmeden HTML sayfasına eklenmesiyle ortaya çıkar. Bu durumda, normalde metin olarak görüntülenmesi gereken bir satır, tarayıcı tarafından HTML veya JavaScript kodunun bir parçası olarak algılanabilir.
Basit bir örnek olarak, yorum özelliği olan bir siteyi düşünelim. Kullanıcı bir mesaj girer, sunucu bunu kaydeder ve diğer ziyaretçilere gösterir. Eğer uygulama, girilen veriyi doğrulamadan doğrudan HTML'e eklerse, saldırgan JavaScript çalıştırılmasına yol açacak bir yapı eklemeyi deneyebilir.
XSS'i basitçe, veri ile komutların karışması olarak düşünebiliriz. Kullanıcı siteye sadece bilgi gönderebilmelidir: isim, yorum, arama sorgusu ya da başka bir metin. Ancak geliştirici hatası nedeniyle tarayıcı bu verinin bir kısmını çalıştırılacak bir talimat olarak görebilir.
Cross Site Scripting adının kökeni, saldırının her zaman bir siteden diğerine kod taşımayı gerektirmemesindendir. Asıl önemli olan, güvenilmeyen kodun kullanıcının güvendiği bir sayfa bağlamında çalıştırılmasıdır.
Klasik bir saldırıda, saldırgan sunucuya, veritabanına, yönetici paneline veya dosya sistemine erişmeye çalışır. XSS ise farklı işler: burada esas hedef, ziyaretçinin tarayıcısıdır.
Saldırganın sunucunun tüm kontrolünü ele geçirmesi gerekmez. Sitenin dışarıdan alınan verileri sayfaya güvensiz şekilde eklediği bir açık bulmak yeterlidir. Kurban bu tür bir sayfayı açınca, zararlı kod kendi cihazında, tarayıcıda çalışır.
Bu yüzden XSS, örneğin SQL enjeksiyonundan ayrılır. SQL enjeksiyonunda, güvensiz veriler veritabanı sorgusuna dahil olurken, XSS'de bunlar tarayıcı tarafında çalıştırılabilir koda dönüşür. Sunucu tarafı açıklar hakkında daha fazlasını SQL enjeksiyonu nedir, tehlikeleri, türleri ve korunma yöntemleri adlı makalede okuyabilirsiniz. Her iki saldırı da güvensiz veri işleme ile ilgilidir, ancak uygulamanın farklı bölümlerini etkiler.
XSS saldırısı, web uygulamasının güvensiz bir kaynaktan veri almasıyla başlar. Bu, bir yorum, arama sorgusu, URL parametresi, kullanıcı adı veya ziyaretçinin değiştirebileceği başka bir bilgi olabilir. Site bu verileri sayfaya güvenli şekilde dahil etmezse, tarayıcı bunları metin yerine HTML veya JavaScript olarak algılayabilir.
Kritik hata, sayfa oluşturulurken meydana gelir. Sunucu veya istemci tarafı JavaScript, alınan değeri tarayıcının HTML veya kod beklediği yere yerleştirir. Özel olarak hazırlanmış veriler, dokümanın yapısını değiştirebilir ve tarayıcıyı beklenmeyen bir komutu çalıştırmaya zorlayabilir.
Tarayıcı, kodun site geliştiricisi mi yoksa saldırgan tarafından mı eklendiğini bilmez. JavaScript sayfa içinde ve koruma mekanizmaları tarafından engellenmediyse, mevcut sitenin bağlamında çalışır.
Tipik bir zincir, bir form veya sorgu parametresiyle başlar. Kullanıcı veriyi siteye gönderir, uygulama bu veriyi alır ve HTML sayfasına ekler. Doğru işlenirse, özel karakterler tarayıcıda normal metin olarak görünür.
Eğer kaçışlama yapılmazsa, içerik HTML'in yapısını değiştirebilir. Böylece tarayıcı, gelen sayfayı artık eklenen elementler ve olay işleyicileriyle birlikte işler. Sorun yalnızca kullanıcı girdisinin varlığında değil; hangi bağlamda ve nasıl eklendiğinde ortaya çıkar.
Bazı durumlarda, veri sunucuya kaydedilmeden de saldırı gerçekleşebilir. Uygulama, adres çubuğundan veya başka bir kaynaktan aldığı değeri doğrudan DOM'a eklerse, XSS hem klasik sunucu taraflı sitelerde hem de JavaScript ile oluşturulan modern web uygulamalarında ortaya çıkabilir.
XSS'in etkileri, sitenin yapısına ve tarayıcı ayarlarına bağlıdır. Zararlı script, sayfanın erişebildiği içeriği okuyabilir, arayüz elemanlarını değiştirebilir, kullanıcı hareketlerini izleyebilir veya açık sekme adına istekler gönderebilir.
Örneğin, saldırgan gerçek site içindeki arayüzün bir kısmını sahte bir giriş formu veya orijinaliyle neredeyse aynı başka bir öğeyle değiştirebilir. Çünkü bu işlem gerçek site üzerinde yapılır; kullanıcı, sayfanın bir kısmının zararlı script ile değiştirildiğini fark etmeyebilir.
Ayrıca JavaScript, mevcut sayfanın sahip olduğu haklarla işlemler gerçekleştirebilir. Kullanıcı zaten giriş yaptıysa, tarayıcı onun oturum bilgilerini aynı siteye yapılan isteklere otomatik olarak ekleyebilir. Bu nedenle, XSS yalnızca bilgi okumak için değil, kurban adına bazı işlemleri yürütmek için de kullanılabilir.
En bilinen senaryolardan biri, oturum çerezleriyle ilgilidir. Girişten sonra site, tarayıcıya oturum kimliği verir, böylece kullanıcı her istekte parolasını yeniden girmek zorunda kalmaz.
Bu çerez JavaScript ile okunabiliyorsa, başarılı bir XSS saldırısı değerin saldırgana iletilmesini sağlayabilir. Yakalanan kimlik, bazen parolayı bilmeden giriş yapılmış gibi davranmak için kullanılabilir.
Modern siteler bu riski HttpOnly özelliğiyle azaltır; bu, JavaScript'in çerezi doğrudan okumasını engeller. Ancak bu, XSS'i tamamen ortadan kaldırmaz. Zararlı kod, yine de sayfayla etkileşime geçebilir ve tarayıcı aracılığıyla izin verilen işlemleri başlatabilir. Bu yüzden oturum koruması, XSS açığını tamamen kapatmanın yerine geçmez; ikisi birlikte kullanılmalıdır.
XSS saldırıları, zararlı kodun sayfaya nasıl girdiğine ve hangi aşamada çalıştığına göre ayrılır. En sık karşılaşılanlar: Stored XSS, Reflected XSS ve DOM XSS. Kullanıcı açısından sonuç aynı olabilir - tarayıcıda yabancı bir JavaScript çalışır - ancak açığın nedeni ve kodun iletim şekli farklıdır.
Stored XSS (kalıcı XSS), zararlı verinin site tarafında saklanıp, daha sonra otomatik olarak diğer kullanıcılara gösterilmesiyle ortaya çıkar. Kaynak; bir yorum, mesaj, profil açıklaması, forum gönderisi veya veritabanında tutulan başka bir alan olabilir.
Bu senaryoda saldırganın her seferinde kurbana özel bir bağlantı göndermesi gerekmez. Bir defa zararlı kodu açık olan bölüme eklemesi yeterlidir; ardından ilgili sayfayı açan herkesin tarayıcısında bu kod çalışabilir.
Bu nedenle Stored XSS, genellikle en ciddi siteler arası komut dosyası türü olarak değerlendirilir. Eğer açık olan sayfa popülerse, tek bir zararlı script çok sayıda kullanıcıyı etkileyebilir.
Reflected XSS (yansıyan XSS) ise farklı çalışır. Zararlı veri, site veritabanında saklanmaz; istekle birlikte gelir, hemen oluşturulan sayfaya eklenir ve kullanıcıya döner.
Örneğin, site arama sorgusunu sonuç başlığında gösteriyorsa ya da URL parametresini hata mesajında kullanıyorsa ve değerler güvenli şekilde işlenmezse, özel olarak hazırlanmış bir istekle JavaScript çalıştırılabilir.
Bu saldırı türü genellikle kullanıcıyı özel bir bağlantıyı açmaya zorlamayı veya belirli bir istek göndermesini gerektirir. Bu yüzden Reflected XSS, sıkça sosyal mühendislik, oltalama veya gizli bağlantılarla birlikte kullanılır.
DOM XSS, doğrudan tarayıcıda ve istemci tarafı JavaScript'in veri işleme şekliyle ilgilidir. Sunucu, tamamen güvenli bir sayfa döndürebilir; ancak açık, sayfa yüklendikten sonra ortaya çıkar.
Örneğin, bir script URL'den, # işaretinden sonraki parçadan, sorgu parametresinden veya başka bir kaynaktan aldığı değeri güvensiz şekilde sayfaya eklerse, saldırgan DOM'u değiştirip kod çalıştırabilir.
DOM XSS'in temel farkı, problemin uygulamanın istemci tarafı mantığında olmasıdır. Zararlı veri sunucuya hiç gitmeyebilir; bu nedenle sunucu günlüklerinden açığı tespit etmek daha zordur.
Özetle; Stored XSS kaydedilmiş verilerle, Reflected XSS sunucunun anında yanıtında, DOM XSS ise tarayıcıda verinin güvensiz işlenmesiyle ilgilidir. Hepsinin ortak nedeni, uygulamanın güvensiz verileri, tarayıcının kod olarak algılayabileceği bir bağlama sokmasına izin vermesidir.
XSS'in tehlikesi, zararlı kodun kullanıcının zaten güvendiği gerçek site içinde çalışmasında yatar. Sayfa görsel olarak tamamen normal görünebilir; ancak tarayıcı arka planda site geliştiricilerinin öngörmediği işlemleri yürütüyor olabilir.
Sonuçlar, uygulamanın sunduğu imkanlara bağlıdır. Bir sitede XSS yalnızca arayüzün değişmesine yol açabilir, diğerinde ise oturum açmış kullanıcı adına istekler göndermeye veya hassas verilere erişmeye olanak tanıyabilir.
Zararlı JavaScript, sayfadaki bilgileri okuyabilir, arayüzdeki etkileşimleri izleyebilir ve verileri dış bir sunucuya gönderebilir. Özellikle kullanıcı panelleri, dahili hizmetler ve yönetim panelleri gibi hassas sayfalarda, kullanıcıya sunulan bilgiler dışarıdan birine açık değildir.
Kullanıcı zaten oturum açtıysa, tarayıcı açık siteyi güvenilir olarak görmeye devam eder ve isteklerle birlikte oturum verilerini otomatik olarak gönderir. Bu, zararlı script'in bazı işlemleri kurban adına başlatmasına imkan tanır; oturum kimliği doğrudan okunamasa bile.
XSS, sayfa DOM'unu değiştirmeye izin verdiğinden, saldırgan yeni öğeler ekleyebilir veya mevcut olanları değiştirebilir. Örneğin, gerçek form yerine sahte bir giriş penceresi, şifreyi tekrar girmenizi isteyen bir mesaj ya da başka bir kaynağa yönlendiren bir düğme gösterebilir.
Bu tür bir değişiklik, doğrudan gerçek alan adı üzerinde gerçekleştiği için özellikle tehlikelidir. Kullanıcı alışık olduğu adresi görür ve arayüzün bir kısmının zararlı script ile değiştirildiğini fark etmeyebilir.
XSS ile bağlantılar değiştirilebilir, uyarılar gizlenebilir, sayfa içerikleri değiştirilebilir veya kullanıcı başka bir siteye yönlendirilebilir. Bazı durumlarda, bu saldırı oltalama aşamasında ek bir adım olarak da kullanılabilir.
HTTPS kullanımı XSS'e karşı koruma sağlamaz. HTTPS, tarayıcı ile sunucu arasındaki bağlantıyı şifreler ve trafiğin yolda okunmasını veya değiştirilmesini engeller; ancak sayfa içindeki JavaScript'in güvenli olup olmadığını kontrol etmez.
Eğer yasal bir site sunucusu, zararlı script içeren bir sayfa oluşturmuşsa ya da istemci kodu güvensiz bir DOM yaratmışsa, tarayıcı bu verileri tamamen güvenli bir HTTPS bağlantısıyla alır ve yine de çalıştırır.
Bu, XSS ile trafik dinleme arasındaki temel farktır. "Ortadaki adam" (MITM) saldırısında, saldırgan bağlantıdaki verileri değiştirmeye çalışır; XSS'de ise zararlı kod doğrudan güvenilir web sayfasının içinde yer alır. Bu mekanizma hakkında daha fazlasını MITM saldırısı nedir, türleri, korunma yöntemleri ve HTTPS'in rolü başlıklı yazıda bulabilirsiniz.
Siteler arası komut dosyasına karşı koruma, tek bir temel ilkeye dayanır: Kullanıcıdan veya başka bir dış kaynaktan gelen veriler otomatik olarak güvenli kabul edilmemelidir. Uygulamanın, bu verilerin nereye eklendiğini ve tarayıcı tarafından nasıl yorumlanacağını kontrol etmesi gerekir.
Tek bir doğrulama yeterli değildir. Güvenilir koruma genellikle doğru çıktı kaçışlama, güvenli DOM işlemleri, script çalıştırma kısıtlamaları ve oturum koruma önlemlerinin birleşimini içerir.
XSS'e karşı en önemli önlem, kullanıcı verilerini HTML kodu yerine metin olarak yansıtmaktır. Yorum, isim veya arama sorgusu girildiğinde, tarayıcı özel karakterleri metnin bir parçası olarak algılamalıdır, HTML öğesi olarak değil.
Kaçışlama yöntemi ise bağlama göre değişir. HTML içi, öznitelikler, URL veya JavaScript dizeleri farklı şekilde işlenmelidir. Hata, uygulamanın her durum için aynı yöntemi kullanmasında ya da verileri doğrudan sayfaya eklemesinde oluşur.
Modern şablon motorları ve web çerçevelerinin çoğu, çıktıyı otomatik olarak kaçışlar. Ancak geliştirici bu özelliği kapatır veya ham HTML eklerse koruma ortadan kalkar.
Doğrulama, giriş verilerinin kabul edilebilir formatını sınırlandırmaya yardımcı olur. Örneğin, yaş alanı HTML kodu kabul etmemeli, dosya adı ise rastgele kontrol karakterlerini almamalıdır.
Uygulama gerçekten HTML kabul etmeli ise (örneğin makale editöründe veya biçimlendirmeli yorumlarda), özel karakterleri yasaklamak yeterli olmaz. Bu durumda, sadece belirli güvenli etiketlere ve özniteliklere izin verilir, potansiyel olarak tehlikeli öğeler temizlenir.
Ancak giriş filtresi tek başına yeterli değildir. Doğru kontrol edilen veriler bile, daha sonra farklı bir bağlamda sayfaya eklenirse sorun çıkarabilir. Bu nedenle koruma, verinin sayfaya eklenme noktasında uygulanmalıdır.
Ek koruma katmanı olarak Content Security Policy (CSP) kullanılabilir. CSP ile site, tarayıcının JavaScript'i nereden yükleyip çalıştırabileceğini belirler ve onaylanmamış scriptlerin çalışmasını engeller.
Doğru yapılandırılmış bir CSP, XSS'in sonuçlarını büyük ölçüde azaltabilir, ancak açığın kendisini düzeltmenin yerine geçmez. Uygulama hala kullanıcı verilerini güvensiz şekilde sayfaya ekliyorsa, sorun devam eder.
İstemci tarafı JavaScript'e özel özen gösterilmelidir. Normal metin çıkışı için textContent gibi işlemler kullanılmalı, dizgiyi HTML olarak yorumlayan yöntemlerden kaçınılmalıdır. innerHTML gibi yapılar, sadece içerik tamamen kontrol altındaysa veya önceden temizlenmişse kullanılmalıdır.
XSS tamamen engellenemese de, potansiyel zarar azaltılabilir. Oturum çerezleri için HttpOnly özelliği kullanılır; bu, JavaScript'in çerezi doğrudan okumasını engeller.
Secure özelliği, çerezin sadece HTTPS üzerinden iletilmesini sağlar; SameSite ise, diğer sitelerden yapılan isteklerde çerezin gönderilmesini kontrol etmeye yardımcı olur. Bu mekanizmalar XSS'i ortadan kaldırmaz, ancak bazı oturum hırsızlığı veya kötüye kullanma senaryolarını zorlaştırır.
Pratikte, etkili koruma çok katmanlıdır: Çıktı kaçışlanır, tehlikeli HTML temizlenir, istemci kodu güvensiz DOM işlemlerinden kaçınır, CSP scriptleri sınırlar ve çerezler tarayıcıda ek olarak korunur.
XSS saldırısı, bir sitenin güvensiz verilerin kullanıcı tarayıcısında çalıştırılabilir koda dönüşmesine izin verdiği durumlarda ortaya çıkar. Zararlı JavaScript, kaydedilmiş veriler, sorgu parametreleri veya güvensiz DOM işlemleri yoluyla sayfaya sızabilir; bu nedenle Stored XSS, Reflected XSS ve DOM XSS türlerinde açık ararken farklı yöntemler gerekebilir.
En iyi koruma yolu, kullanıcı verilerini HTML ve JavaScript ile güvenli şekilde karıştırmamaktır. Çıktı kaçışlama, izin verilen HTML'in temizlenmesi, dikkatli DOM işlemleri, Content Security Policy ve korumalı çerezler birlikte kullanılmalıdır. Web uygulaması veriyi ve çalıştırılabilir kodu ne kadar erken ayırırsa, sıradan bir giriş alanının XSS saldırı noktası olma ihtimali de o kadar azalır.