Skip to content

Bölüm 9 / 11

OWASP Top 10

SQL injection, XSS, IDOR, güvenlik yanlış yapılandırması.

17 dakikalık okuma

Bu hat boyunca kimlik tarafını kurduk. Şimdi geriye kalan her şeyin ortak listesi var: OWASP Top 10 — web uygulamalarındaki en yaygın ve en etkili zafiyet kategorileri. Bu ders bir liste ezberi değil; her kategoriyi mekanizma düzeyinde açıp senin daha önce yazdığın koda bağlıyor: 7. hattaki parametreli sorgu, 12-09'daki beyaz liste, 11. hattaki dangerouslySetInnerHTML. Ağırlık iki başlıkta: bozuk erişim kontrolü (3. dersin devamı) ve enjeksiyon — SQL ve XSS. Sonunda 13-04'te açık bıraktığımız borç kapanıyor: CSP.

01Ne öğreneceksin

  • OWASP Top 10 ne değildir: neden bir uyumluluk kontrol listesi sayılmaz
  • A01 Bozuk erişim kontrolü: IDOR'un kardeşleri — yol geçişi, kütle atama, zorla gezinme, CORS yanlış yapılandırması
  • SQL enjeksiyonu mekanizması, parametreli sorgunun neden işe yaradığı ve ORM'in yalancı güvenliği; kör enjeksiyon; komut enjeksiyonu
  • XSS üç tür (yansıyan / saklanan / DOM tabanlı), bağlama göre çıktı kodlama ve çerçevelerin kaçış kapıları
  • CSP: nonce, unsafe-inline ve raporlama modu — XSS'e karşı ikinci savunma hattı
  • Kalan kategoriler: kriptografik hatalar, güvensiz tasarım, yanlış yapılandırma + güvenlik başlıkları tablosu, eski bileşen, bütünlük, loglama
  • SSRF ve bulut metadata servisi; dosya yükleme kontrol listesi

02Liste ne işe yarar, ne işe yaramaz

OWASP Top 10, gerçek uygulamalardan toplanan zafiyet verilerine dayanan, birkaç yılda bir güncellenen bir farkındalık belgesidir. Kategoriler yaygınlık, istismar edilebilirlik ve etkiye göre sıralanır. Değeri, "nereye bakmalıyım" sorusuna veri temelli bir cevap vermesidir.

Ne değildir: tam bir güvenlik standardı değildir (onun için ASVS gibi belgeler vardır), bir uyumluluk kontrol listesi değildir ve "bu on maddeyi geçtim, güvenliyim" anlamına gelmez. Kategoriler geniştir: "bozuk erişim kontrolü" başlığı altında birbirinden çok farklı onlarca zafiyet biçimi vardır. Doğru kullanım şudur: listeyi tehdit modelinin (1. ders) girdi listesi olarak kullan, kendi sisteminde her kategorinin karşılığını ara.

Bir de sıralamanın kendisi bilgi taşır: erişim kontrolü listenin başındadır. Yani sahadaki en yaygın ve en etkili sorun egzotik bir kriptografi açığı değil, "kontrol edilmesi gereken yerde kontrol edilmemiş olması"dır. Kıdemli bir gözün ilk baktığı yer burasıdır.

03A01 — Bozuk erişim kontrolü

3. derste IDOR'u işledik: rol kontrol edilip sahiplik unutulması. Aynı kategorinin diğer yüzleri şunlardır ve hepsi aynı kök hataya çıkar — kararın istemciye bırakılması:

BiçimNasılSavunma
IDOR/basvuru/{id} — başkasının kimliği denenirKimlik oturumdan; sahiplik sorgunun koşulunda (3. ders, 8. ders)
Zorla gezinmeMenüde görünmeyen /admin/... yolu doğrudan yazılırGüvenli varsayılan: FallbackPolicy (8. ders)
Yol geçişi?dosya=../../etc/passwd ya da ..%2f..%2fKullanıcı girdisi yol birleştirmede kullanılmaz; kimliğe göre dosya eşlemesi; çözümlenmiş yolun kök dizin altında olduğu doğrulanır (12-04)
Kütle atamaGövdeye "rol":"yonetici" eklenir, model bağlama yazarAyrı DTO; alan beyaz listesi; zod .strict() (12-09)
Metot atlamasıGET korunmuş, aynı işi yapan PUT unutulmuşKontrol uç bazında değil işlem bazında düşünülür
CORS yanlış yapılandırmaGelen Origin'i aynen yansıtmak + credentials: trueBeyaz liste; joker ile kimlik bilgisi birlikte kullanılmaz

Son satır 12-07 ile 13-04'ün birleştiği yerdir ve inceliklidir. CORS bir güvenlik önlemi değil bir gevşetme mekanizmasıdır; ama yanlış gevşetilirse zafiyet üretir. Klasik hata, "hangi köken gelirse ona izin verelim" diye gelen Origin başlığını yanıta aynen kopyalamak ve üstüne Access-Control-Allow-Credentials: true eklemektir. Sonuç: herhangi bir site, kullanıcının çerezleriyle senin API'ni çağırıp yanıtı okuyabilir. Bu artık CSRF değil, doğrudan veri hırsızlığıdır. Kural: izin verilen kökenler sabit bir listeden gelir ve joker (*) ile kimlik bilgisi asla birlikte kullanılmaz.

04Enjeksiyon — SQL ve komut

Enjeksiyonun tek cümlelik tanımı: veri olması gereken şeyin kod olarak yorumlanması. Kullanıcı girdisi bir yorumlayıcıya (SQL motoru, kabuk, LDAP, XPath, şablon motoru) gönderilirken veri ile komut aynı kanaldan gidiyorsa, girdi komutu değiştirebilir.

-- ZAFİYETLİ: dize birleştirme
var sql = "SELECT * FROM Basvurular WHERE Eposta = '" + eposta + "'";

-- Girdi:  ' OR '1'='1' --
-- Sonuç:  SELECT * FROM Basvurular WHERE Eposta = '' OR '1'='1' --'
--         → tüm tablo döner

-- DOĞRU: parametreli sorgu — girdi ASLA sorgu metnine girmez
var sql = "SELECT * FROM Basvurular WHERE Eposta = @eposta";
cmd.Parameters.Add("@eposta", SqlDbType.NVarChar, 320).Value = eposta;

Parametreli sorgu neden işe yarar? Çünkü sorgu metni ve veri ayrı kanallardan gider: veritabanı önce sorgu planını kurar, sonra parametre değerlerini yerleştirir. Değer içinde tırnak, noktalı virgül ya da DROP olması hiçbir şeyi değiştirmez — o artık kod değil, veridir. Bu, "kaçış karakteri ekleyerek temizlemekten" kategorik olarak daha güçlüdür; kaçış listeleri her zaman eksiktir, kanal ayrımı ise yapısaldır.

ORM'in yalancı güvenliği. "Entity Framework kullanıyorum, enjeksiyon olmaz" cümlesi yanlıştır. EF Core LINQ sorgularını parametreli üretir, evet — ama üç kapı açık kalır: ham SQL çalıştırma (FromSqlRaw, ExecuteSqlRaw), dinamik sıralama/filtreleme için dize birleştirme, ve saklı yordamın içinde yapılan dinamik SQL. 12-09'daki kural burada da geçerlidir: parametre olamayan şeyler — tablo adı, sütun adı, ASC/DESC — birleştirme ile değil beyaz liste ile konur.

// Dinamik sıralama: parametre kullanılamaz → beyaz liste ZORUNLU
static readonly HashSet<string> IzinliSutunlar = new() { "olusturma", "unvan", "durum" };
var sutun = IzinliSutunlar.Contains(istek.Sirala) ? istek.Sirala : "olusturma";
var yon   = istek.Yon == "desc" ? "DESC" : "ASC";
var sql   = $"SELECT ... ORDER BY {sutun} {yon}";   // her iki değer de KAPALI kümeden geldi

Kör enjeksiyon. Uygulama hata mesajı ya da veri döndürmese bile saldırı mümkündür: saldırgan doğru/yanlış koşullar sokup yanıtın farkına bakar (boolean tabanlı) ya da WAITFOR DELAY / pg_sleep ile süreye bakar (zaman tabanlı). Bu yüzden "hata mesajlarını gizledik, güvendeyiz" yanlıştır; hata mesajını gizlemek bilgi ifşasını azaltır ama enjeksiyonu kapatmaz.

Komut enjeksiyonu aynı hatanın kabuk versiyonudur ve Node tarafında 12-04'ün devamıdır: exec("convert " + dosyaAdi) bir kabuk çağırır ve ;, |, $( ) karakterleri komut çalıştırır. Doğrusu kabuğu hiç devreye sokmamaktır: execFile/spawn ile program ve argümanları ayrı ayrı verilir. Aynı ilke: kanal ayrımı.

Aynı kategorinin diğer üyeleri: NoSQL enjeksiyonu (sorgu nesnesine {"$ne": null} gibi operatör kaçırmak — girdi tipini doğrulamamaktan doğar), LDAP ve XPath enjeksiyonu, ve sunucu tarafı şablon enjeksiyonu (kullanıcı girdisini şablon kaynağı olarak kullanmak).

05XSS — üç tür ve bağlama göre kodlama

XSS, enjeksiyonun tarayıcı tarafındaki hâlidir: saldırganın verisi, sayfada kod olarak çalışır. Betik senin kökeninde çalıştığı için oturum çerezine (HttpOnly olsa bile isteğe otomatik eklenir), sayfadaki CSRF jetonuna ve kullanıcının gördüğü her şeye erişir — 13-04'te "XSS varsa CSRF savunması anlamsızdır" derken kastettiğimiz budur.

TürNasılÖrnek
YansıyanGirdi istekle gelir, yanıtta geri yazılırArama sonucu sayfasında sorgu metninin kodlanmadan basılması; saldırı bağlantıyla yayılır
SaklananGirdi veritabanına yazılır, sonra herkese servis edilirYorum/açıklama alanı — en tehlikelisi, her ziyaretçiyi etkiler
DOM tabanlıSunucu hiç görmez; istemci betiği URL'den okuyup DOM'a yazarelement.innerHTML = location.hash

Asıl savunma çıktı kodlamasıdır ve bağlama göre değişir. Aynı veri HTML gövdesinde, öznitelik içinde, JavaScript dizesinde ve URL'de farklı kodlanır:

HTML gövdesi     : < > & " '  →  &lt; &gt; &amp; ...
HTML özniteliği  : ayrıca tırnak içine alınmalı — tırnaksız öznitelikte boşluk yeni öznitelik açar
JavaScript içi   : HTML kodlaması BURADA İŞE YARAMAZ; veri JS'e ancak JSON olarak geçirilir
URL parametresi  : yüzde kodlama; ayrıca "javascript:" şeması engellenmeli
CSS içi          : ayrı kurallar — kullanıcı girdisini CSS'e koymamak en iyisi

İyi haber: modern çerçeveler bunu varsayılan olarak yapar. Angular interpolasyonu, React'in {deger} ifadesi ve Razor'ın @deger çıktısı otomatik kodlar. Kötü haber: hepsinin bir kaçış kapısı vardır ve XSS'lerin çoğu oradan girer:

React   : <div dangerouslySetInnerHTML={{ __html: veri }} />
Angular : [innerHTML]="veri"  ve  DomSanitizer.bypassSecurityTrustHtml(veri)
Razor   : @Html.Raw(veri)
Vanilla : element.innerHTML = veri   ·   document.write(veri)   ·   eval(veri)

Bu API'lerin adları bilerek rahatsız edicidir. Kullanılmaları gerekiyorsa (zengin metin editörü çıktısı gibi) tek doğru yol sunucu tarafında olgun bir HTML temizleyiciden geçirmektir — beyaz listeli, bakımlı bir kütüphane. Kendi düzenli ifadenle etiket temizlemek çalışmaz; saldırı yüzeyi (<img onerror>, <svg onload>, kodlama varyasyonları) düzenli ifadeyle kapatılamayacak kadar geniştir.

DOM tabanlı XSS için ek kural: innerHTML yerine textContent, setAttribute yerine güvenli özellik atamaları; ve URL'den gelen değerlerin şemasının doğrulanması (href'e javascript: yazılabilir).

06CSP — 13-04'ün açık borcu

İçerik güvenliği politikası (Content Security Policy), tarayıcıya "bu sayfada hangi kaynaklardan kod/stil/görsel yüklenebilir" diyen bir yanıt başlığıdır. XSS'i önlemez — asıl savunma hâlâ çıktı kodlamasıdır — ama bir XSS'in işe yaramasını engelleyebilir: enjekte edilen betik çalışamaz ya da çaldığı veriyi dışarı gönderemez. Klasik derinlemesine savunma katmanıdır.

Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'nonce-r4nd0m123';   ← yalnız bu nonce'a sahip inline betikler çalışır
  style-src  'self';
  img-src    'self' data:;
  connect-src 'self' https://api.ornek.gov.tr;
  frame-ancestors 'none';                ← clickjacking savunması (X-Frame-Options'ın yerini aldı)
  object-src 'none'; base-uri 'self'; form-action 'self'

<script nonce="r4nd0m123"> /* her yanıtta YENİ üretilen rastgele değer */ </script>

Üç pratik nokta. Birincisi: 'unsafe-inline' yazmak politikayı büyük ölçüde anlamsızlaştırır — enjekte edilen inline betik de çalışır. Doğru yol her yanıtta üretilen bir nonce ya da betik özeti (hash) kullanmaktır; 'unsafe-eval' de aynı şekilde kaçınılması gerekendir. İkincisi: CSP'yi mevcut bir uygulamaya eklemek genelde bir şeyleri kırar; bu yüzden önce Content-Security-Policy-Report-Only ile yayına alınır, raporlar toplanır ve politika oradan sıkılaştırılır. Üçüncüsü: frame-ancestors 'none' ile clickjacking savunması aynı başlıkta halledilir — sayfanın başka bir sitenin iframe'ine gömülüp kullanıcıya görünmez tıklatma yaptırılması engellenir.

07Kalan kategoriler ve güvenlik başlıkları

KategoriTipik hâliBu yol haritasında
Kriptografik hatalarHassas veri düz metin; parolada hızlı hash; kendi şifreleme algoritmanı yazmak; sabit IV; zayıf rastgelelik2. ders (TLS), 3. ders (parola), 14. hat
Güvensiz tasarımKod doğru ama tasarım yanlış: iş akışında yetki adımı hiç yok, oran sınırı düşünülmemiş1. ders (tehdit modeli)
Yanlış yapılandırmaVarsayılan parola; açık Swagger; ayrıntılı hata sayfası; gereksiz açık port; eksik güvenlik başlıkları; dizin listelemeAşağıdaki tablo, 10. ders
Eski/zafiyetli bileşenGüncellenmemiş paketler; terk edilmiş bağımlılıklar; envanter yokluğu12-03 (npm), 18. hat (boru hattında tarama)
Kimlik doğrulama hatalarıZayıf parola politikası; oran sınırı yok; oturum yönetimi hataları3-5. dersler
Yazılım/veri bütünlüğüİmzasız güncelleme; güvensiz seri hâlden çıkarma; CI/CD boru hattının ele geçirilmesi18. hat
Loglama ve izleme eksikliğiSaldırı fark edilmiyor; log yok ya da PII dolu; alarm yok12-11 (yapılandırılmış log, redaksiyon), 14. hat (SIEM)
SSRFSunucuya, saldırganın belirlediği adrese istek attırmak8. bölüm

Güvenlik başlıkları, yanlış yapılandırma kategorisinin en ucuz kazancıdır; birkaç satır ara yazılımla eklenir:

BaşlıkNe yapar
Content-Security-PolicyKaynak beyaz listesi; XSS'in etkisini sınırlar (6. bölüm)
Strict-Transport-SecurityHTTPS zorunluluğu (2. ders)
X-Content-Type-Options: nosniffTarayıcının içerik türünü tahmin etmesini kapatır — yüklenen dosyanın betik olarak yorumlanmasını önler
Referrer-PolicyDış sitelere giden Referer bilgisini kısar (URL'deki jeton/kimlik sızıntısı)
Permissions-PolicyKamera, mikrofon, konum gibi tarayıcı yeteneklerini kapatır
Cache-Control: no-storeKimlikli yanıtların vekil/tarayıcı önbelleğinde kalmasını engeller

Aynı başlıkta bir de çıkarma işi vardır: Server, X-Powered-By, X-AspNet-Version gibi sürüm sızdıran başlıklar kaldırılır. Bu tek başına bir savunma değildir (belirsizlik yoluyla güvenlik — 1. ders), ama otomatik tarayıcıların işini zorlaştırır ve maliyeti sıfırdır.

08SSRF ve dosya yükleme

SSRF (sunucu tarafı istek sahteciliği), uygulamanın kullanıcı tarafından verilen bir adrese istek atmasıdır: "şu URL'deki görseli içe aktar", "webhook adresini test et", "PDF'i şu adresten çek". Saldırgan adresi değiştirir ve sunucuyu kendi eli gibi kullanır — sunucu, saldırganın erişemediği iç ağa erişebilir.

Saldırganın denediği adresler:
  http://169.254.169.254/latest/meta-data/    ← bulut metadata servisi: geçici kimlik bilgileri!
  http://localhost:5432/  ·  http://10.0.0.7/admin      ← iç servisler, yönetim panelleri
  file:///etc/passwd  ·  gopher://...                    ← şema değiştirme

İlk satır SSRF'i "ilginç" olmaktan çıkarıp kritik yapan şeydir: bulut ortamlarında metadata servisi, makinenin rolüne ait geçici kimlik bilgilerini döndürür; SSRF ile onu okuyan saldırgan bulut hesabında yetki kazanır. Savunma katmanları: beyaz liste (izin verilen alan adları/şemalar — kara liste yetersizdir), yalnız http/https şemalarına izin, yönlendirmelerin takip edilmemesi ya da her adımda yeniden doğrulanması (DNS rebinding ve yönlendirmeyle beyaz liste atlatılır), çıkış trafiğinin ağ düzeyinde kısıtlanması ve metadata servisine erişimin kapatılması. Ayrıca yanıtın gövdesi kullanıcıya aynen geri verilmez — verilirse kör SSRF, okunabilir SSRF'e döner.

Dosya yükleme kendi başına bir kontrol listesidir ve birden çok kategoriye dokunur:

  • Dosya adına asla güvenilmez. Sunucuda üretilen yeni bir ad kullanılır; kullanıcının adı yalnızca gösterim için saklanır (yol geçişi ve üzerine yazma riski — 12-04).
  • Tür doğrulaması uzantıyla yapılmaz. İçerik türü başlığı da istemciden gelir. İçeriğin kendisi (imza baytları) kontrol edilir ve beyaz liste uygulanır.
  • Yüklenen dosyalar çalıştırılabilir olmamalıdır. Web kök dizininin dışında saklanır; mümkünse ayrı bir alan adından servis edilir ki bir HTML dosyası yüklense bile senin kökeninde çalışmasın (XSS'e dönüşmesin).
  • Content-Disposition: attachment + nosniff ile tarayıcıda çalıştırılması yerine indirilmesi sağlanır.
  • Boyut ve kaynak sınırları: istek boyutu sınırı, disk kotası ve arşiv açılıyorsa açılmış boyut sınırı (zip bomb). 12-05'teki stream disiplini burada bellek koruması sağlar.
  • Erişim kontrolü indirmede de vardır: yüklenen belgeyi kimin indirebileceği A01 sorusudur; tahmin edilemez dosya adı tek başına yetmez.

09Mini alıştırma — kendi uygulamanı kendin kır

Yaklaşık 20 dakika · kendi API'n + tarayıcı; hepsi kendi makinende

  1. SQL enjeksiyonunu üret ve kapat. Bir uçta bilerek dize birleştirmeli sorgu yaz, ' OR '1'='1' -- ile tüm kayıtları döndür. Parametreli sorguya çevir ve aynı girdinin artık yalnızca arandığını gör. Sonra dinamik sıralama ekle: parametre kullanamadığını fark et ve beyaz listeyle çöz.
  2. Kör enjeksiyonu gözle. Hata mesajlarını kapat ve ' AND 1=1 -- ile ' AND 1=2 -- girdilerinde yanıtın farklılaştığını göster. "Hata mesajını gizledim, güvendeyim" cümlesinin neden yanlış olduğunu bir cümleyle yaz.
  3. Üç XSS türünü de dene. (a) Arama sonucunda sorguyu kodlamadan bas — yansıyan; (b) yorum alanına <img src=x onerror=alert(1)> yaz ve başka bir tarayıcıda aç — saklanan; (c) element.innerHTML = location.hash.slice(1) yazan bir sayfa kur — DOM tabanlı. Üçünü de kapat: sunucuda çıktı kodlaması, textContent, ve zengin metin için temizleyici.
  4. CSP'yi devreye al. Önce Content-Security-Policy-Report-Only ile default-src 'self' yayınla ve konsoldaki ihlalleri oku — kaç inline betiğin olduğunu gör. Sonra nonce yaklaşımına geçip politikayı zorunlu hâle getir; (b) şıkkındaki saklanan XSS'in artık çalışmadığını doğrula. CSP'nin XSS'i "önlemediği" ama ne yaptığını yaz.
  5. CORS'u yanlış yapılandır. Gelen Origin'i yansıtan + credentials: true veren bir yapılandırma kur, ikinci bir porttaki sayfadan fetch(..., {credentials:"include"}) ile kimlikli veri çek ve yanıtı okuyabildiğini gör. Beyaz listeye çevirip düzelt. Bunun CSRF'den farkını bir cümlede yaz.
  6. SSRF ve yükleme. "URL'den görsel içe aktar" ucu yaz ve http://127.0.0.1:<kendi portun>/admin vererek sunucunun kendi iç ucunu çağırdığını gör; beyaz liste + şema kontrolü + yönlendirme takip etmeme ile kapat. Ardından yükleme ucuna .html uzantılı bir dosya yükle ve servis edildiğinde tarayıcıda çalıştığını gör; yeni ad üretme, nosniff, Content-Disposition: attachment ve web kökü dışında saklama ile kapat.

10Kendini sına

OWASP Top 10 ne işe yarar, ne değildir? A01'in IDOR dışındaki biçimlerini say; CORS'un yanlış yapılandırılması neden CSRF'den farklı bir zafiyettir?

Gerçek zafiyet verisine dayanan, birkaç yılda bir güncellenen bir farkındalık belgesidir; "nereye bakmalıyım" sorusuna veri temelli cevap verir. Tam bir standart (ASVS gibi) ya da uyumluluk kontrol listesi değildir ve "bu onu geçtim, güvenliyim" anlamına gelmez; kategoriler geniştir. Doğru kullanım, listeyi tehdit modelinin girdi listesi yapmaktır. Sıralamanın kendisi de bilgidir: erişim kontrolü listenin başındadır — en yaygın sorun egzotik bir kripto açığı değil, kontrolün yapılmamış olmasıdır. A01'in biçimleri: IDOR; zorla gezinme (menüde olmayan /admin yolunun doğrudan yazılması); yol geçişi (../../etc/passwd); kütle atama ("rol":"yonetici"); metot atlaması (GET korunmuş, aynı işi yapan PUT unutulmuş); CORS yanlış yapılandırması. Sonuncusu CSRF'den farklıdır: CSRF'de saldırgan yanıtı okuyamaz, yalnız yan etki üretir. Gelen Origin'i aynen yansıtıp Allow-Credentials: true vermek ise herhangi bir sitenin kullanıcının çerezleriyle API'yi çağırıp yanıtı okumasına izin verir — bu doğrudan veri hırsızlığıdır. Kural: sabit beyaz liste; joker ile kimlik bilgisi asla birlikte kullanılmaz.

Enjeksiyonun kök sebebi nedir; parametreli sorgu neden kaçış karakterinden daha güçlüdür? "ORM kullanıyorum, SQL enjeksiyonu olmaz" cümlesinin nesi yanlıştır?

Kök sebep: veri olması gereken şeyin kod olarak yorumlanması — girdi ile komut aynı kanaldan gidiyorsa girdi komutu değiştirir. Parametreli sorgu yapısal olarak üstündür çünkü sorgu metni ve veri ayrı kanallardan gider: motor önce planı kurar, sonra değerleri yerleştirir; değerdeki tırnak veya DROP artık koddur değil veridir. Kaçış listeleri ise her zaman eksiktir (kodlama varyasyonları, çok baytlı karakterler). ORM cümlesi yanlıştır çünkü üç kapı açıktır: ham SQL API'leri (FromSqlRaw/ExecuteSqlRaw), dinamik sıralama/filtreleme için dize birleştirme ve saklı yordamın içindeki dinamik SQL. Parametre olamayan şeyler — tablo adı, sütun adı, ASC/DESC — birleştirmeyle değil beyaz listeyle konur (12-09'un kuralı). Ayrıca kör enjeksiyon vardır: uygulama hata ya da veri döndürmese bile saldırgan doğru/yanlış koşullarla yanıt farkına (boolean) ya da WAITFOR/pg_sleep ile süreye (zaman) bakarak veriyi çıkarabilir — "hata mesajını gizledim" enjeksiyonu kapatmaz. Aynı hatanın kabuk sürümü komut enjeksiyonudur; çözüm kabuğu hiç devreye sokmamaktır (execFile/spawn ile ayrı argümanlar).

XSS'in üç türünü ayır. Çıktı kodlaması neden "bağlama göre"dir ve çerçevelerin kaçış kapıları nelerdir?

Yansıyan: girdi istekle gelir, yanıtta kodlanmadan geri yazılır; saldırı bir bağlantıyla yayılır. Saklanan: girdi veritabanına yazılıp sonra herkese servis edilir — en tehlikelisi, her ziyaretçiyi etkiler. DOM tabanlı: sunucu hiç görmez; istemci betiği URL'den okuyup DOM'a yazar (innerHTML = location.hash). Betik senin kökeninde çalıştığı için HttpOnly çerez de isteğe otomatik eklenir ve CSRF jetonu sayfadan okunur — "XSS varsa CSRF savunması anlamsızdır" cümlesinin sebebi budur. Kodlama bağlama göredir çünkü aynı veri HTML gövdesinde, HTML özniteliğinde, JavaScript dizesinde, URL'de ve CSS'te farklı kaçış kurallarına tabidir; özellikle HTML kodlaması JavaScript bağlamında işe yaramaz — veri JS'e ancak JSON olarak geçirilir, URL'de javascript: şeması engellenir. Çerçeveler varsayılan olarak kodlar; XSS'ler kaçış kapılarından girer: dangerouslySetInnerHTML, [innerHTML] / bypassSecurityTrustHtml, @Html.Raw, düz innerHTML/document.write/eval. Zorunluysa olgun bir HTML temizleyici kullanılır; kendi düzenli ifadenle etiket temizlemek çalışmaz.

CSP ne yapar, ne yapmaz; unsafe-inline ve nonce farkı nedir? SSRF neden kritiktir ve dosya yüklemede hangi kontroller gerekir?

CSP tarayıcıya hangi kaynaklardan kod/stil/görsel yükleneceğini söyleyen bir başlıktır. XSS'i önlemez — asıl savunma çıktı kodlamasıdır — ama bir XSS'in işe yaramasını engelleyebilir: enjekte edilen betik çalışamaz ya da çaldığını dışarı gönderemez; klasik derinlemesine savunma katmanıdır. 'unsafe-inline' yazmak politikayı büyük ölçüde anlamsızlaştırır, çünkü enjekte edilen inline betik de çalışır; doğrusu her yanıtta üretilen bir nonce (ya da betik hash'i) kullanmaktır. 'unsafe-eval' de kaçınılır. Mevcut uygulamada önce Report-Only ile yayına alınıp raporlara göre sıkılaştırılır; ayrıca frame-ancestors 'none' clickjacking savunmasını aynı başlıkta halleder. SSRF kritiktir çünkü sunucu, saldırganın erişemediği iç ağa erişebilir; en çarpıcı hedef bulut metadata servisidir (169.254.169.254) — makinenin rolüne ait geçici kimlik bilgilerini döndürür ve saldırgan bulut hesabında yetki kazanır. Savunma: alan adı/şema beyaz listesi (kara liste yetersiz), yalnız http/https, yönlendirmeleri takip etmemek ya da her adımda yeniden doğrulamak (DNS rebinding), çıkış trafiğini ağ düzeyinde kısmak, metadata erişimini kapatmak ve yanıt gövdesini kullanıcıya aynen geri vermemek. Dosya yükleme: dosya adına güvenilmez (sunucuda yeni ad); tür uzantıyla değil içerik imzasıyla ve beyaz listeyle doğrulanır; dosyalar web kökü dışında, tercihen ayrı bir alan adından servis edilir ki yüklenen HTML senin kökeninde çalışmasın; Content-Disposition: attachment + nosniff; boyut/kota ve arşiv açılım sınırı (zip bomb); ve indirme de bir erişim kontrolü sorusudur — tahmin edilemez ad tek başına yetmez.

11Sınav köşesi

Yazılıda nasıl sorulur

(1) OWASP Top 10 nedir? (2) Broken access control kategorisine hangi zafiyetler girer? (3) IDOR nedir? (4) SQL injection nasıl çalışır, nasıl önlenir? (5) Parametreli sorgu neden güvenlidir? (6) Blind SQL injection nedir? (7) Command injection nedir? (8) XSS türlerini açıklayın. (9) Output encoding neden bağlama göre yapılır? (10) CSP nedir, hangi direktifleri vardır? (11) unsafe-inline neden sakıncalıdır? (12) Clickjacking nedir, nasıl önlenir? (13) Güvenlik başlıklarını sayın ve görevlerini yazın. (14) SSRF nedir, bulut ortamında neden kritiktir? (15) Güvenli dosya yükleme için hangi kontroller yapılır? (16) Security misconfiguration örnekleri nelerdir?

Sözlüde nasıl anlatılır — 2 dakikalık taslak

Düzen: (1) Çerçeve — "Top 10 bir standart değil, veri temelli bir farkındalık listesidir; ben onu tehdit modelimin girdi listesi olarak kullanırım. Sıralamanın kendisi bilgi taşır: en başta erişim kontrolü var — sahadaki asıl sorun egzotik açıklar değil, kontrolün hiç yapılmamış olması." (2) A01 — "IDOR'un kardeşlerini sayarım: zorla gezinme, yol geçişi, kütle atama, metot atlaması ve CORS'un yanlış gevşetilmesi. Sonuncusunda Origin'i yansıtıp credentials açmak, herhangi bir sitenin kimlikli yanıtı okumasına izin verir — bu CSRF'den farklı, doğrudan hırsızlıktır." (3) Enjeksiyon — "Kök sebep veri ile komutun aynı kanaldan gitmesidir; parametreli sorgu kanalları ayırır, o yüzden kaçış karakterinden kategorik olarak güçlüdür. ORM her şeyi çözmez: ham SQL, dinamik sıralama ve saklı yordam içi dinamik SQL açık kapılardır — parametre olamayan şeyleri beyaz listeyle koyarım." (4) XSS ve CSP — "Üç türü ayırırım; asıl savunma bağlama göre çıktı kodlamasıdır ve çerçeveler bunu varsayılan yapar — açıklar dangerouslySetInnerHTML gibi kaçış kapılarından girer. CSP ikinci hattır: XSS'i önlemez, işe yaramasını engeller; unsafe-inline yerine nonce kullanır, mevcut sisteme Report-Only ile sokarım." (5) Kıdem vuruşu — "İki başlığı ayrıca vurgularım: SSRF, bulutta metadata servisinden geçici kimlik bilgisi okunmasına yol açtığı için kritiktir; beyaz liste yetmez, yönlendirmeleri de yeniden doğrularım. Ve dosya yükleme: adı sunucu üretir, türü içerik imzasıyla doğrularım, dosyaları ayrı bir alan adından servis ederim ki yüklenen bir HTML benim kökenimde çalışıp XSS'e dönüşmesin — indirmenin kendisi de bir yetkilendirme sorusudur."