İçeriğe geç
Sedat Özdemir
Yazılar

application-security

WAF Sizi Kurtarmaz: Güvenlik Duvarlarının Arkasındaki İllüzyon ve Acı Gerçekler

Piyasada herkesin 'tek kurşun' çözüm gibi sunduğu WAF (Web Application Firewall) aslında çoğu zaman evinizin kapısına astığınız tül perdeden farksız. Sahadan örneklerle, neden sadece filtrelemeye güvenmemeniz gerektiğini ve gerçek savunmanın kodun derinliklerinde nasıl başladığını inceliyoruz.

Sedat Özdemir
· 3 dk okuma

Selam ekip, bugün biraz damara basacağız. Sektörde nereye gitsem aynı tablo: Şirket binlerce dolar döküp en 'premium' WAF çözümünü almış, kural setlerini 'agresif' moda çekmiş, sonra da arkasına yaslanıp 'Biz güvendeyiz abi' moduna girmiş. Açık konuşalım; WAF kurup web uygulamasını savunmasız bırakmak, çelik kapı taktırıp anahtarı paspasın altına koymaya benziyor. Hatta daha kötüsü, o kapının yanındaki duvarın aslında kartonpiyerden olduğunu unutuyorsunuz.

WAF Bir Kalkan Değil, Sadece Bir Süzgeçtir

Bakın beyler, bayanlar; WAF dediğiniz nane bir 'blackbox' mantığıyla çalışır. Gelen trafiğe bakar, elindeki imzalarla eşleştirir, 'Hah bu XSS'e benziyor' der ve bloklar. Ama Red Team tarafında biz ne yapıyoruz? O imzaya benzemeyen ama aynı işi yapan binlerce varyasyon üretiyoruz. Eğer güvenliğinizi sadece bir cihazın Regex (Düzenli İfade) yeteneğine bıraktıysanız, geçmiş olsun.

Bir sızma testinde veya gerçek bir operasyonda, hedef sistemin önünde sıkı bir WAF varsa ilk yaptığımız şey 'impedance mismatch' dediğimiz olayı kovalamaktır. Yani WAF'ın veriyi anlama biçimiyle, arkadaki uygulama sunucusunun (Node.js, PHP, Python fark etmez) o veriyi yorumlama biçimi arasındaki farkı buluruz.

Kodla Oynayalım: Encoding Sanatı

Basit bir örnek üzerinden gidelim. Bir giriş alanınız var ve WAF <script> etiketini gördüğü an trafiği kesiyor. Çoğu geliştirici 'Tamam işte, koruyor' diyor. Peki ya biz veriyi WAF'ın beklediğinden farklı bir şekilde paketlersek?

WAF bazen URL encoding'i çözer ama double encoding (çift kodlama) karşısında afallayabilir. Ya da daha kötüsü, WAF katmanında 'unicode normalization' yapılmıyorsa vay halinize.

// Zararsızlaştırılmış (Defanged) Örnek
// WAF muhtemelen şunu yakalar:
// <script>alert(1)</script>

// Ama şunu görmeyebilir (Mock-up):
// %253Cscript%253Ealert(1)%253C/script%253E

// Veya Unicode karakterler kullanarak sistemi yanıltmak:
// ˂script˃alert(1)˂/script˃ 
// (Buradaki 'küçüktür/büyüktür' işaretleri aslında farklı karakter kodlarıdır)

Uygulama sunucusu bu veriyi alıp 'normalize' ettiğinde, o garip karakterler tekrar tehlikeli hallerine dönüşür. WAF ise sadece üzerinden geçen anlamsız (onun için) karaktere bakıp geçmiştir.

Business Logic: Makinelerin Anlamadığı Dünya

En sevdiğim kısım burası. WAF istediği kadar zeki olsun, sizin iş mantığınızdaki (business logic) hataları asla yakalayamaz. Bir e-ticaret sitesinde (haydi buna testCompany diyelim) bir kullanıcının sepetindeki ürün fiyatını eksiye düşürmesini hangi WAF engelleyebilir?

POST /api/v1/checkout HTTP/1.1
Host: testCompany.example.com
Content-Type: application/json

{
  "item_id": "super-pahali-laptop",
  "quantity": 1,
  "price": -5000 
}

Eğer backend tarafında price alanı için 'Gelen değer sıfırdan küçük mü?' kontrolü yapılmadıysa, WAF bu paketi tertemiz bir JSON trafiği olarak görür ve içeri buyur eder. Sonuç? Şirketin kasasından size para ödenen bir 'alışveriş' deneyimi. İşte bu yüzden 'Savunma kodda başlar' diyoruz.

Gerçekten Korunmak İçin Reçete

WAF'ı çöpe mi atalım? Tabii ki hayır. O, 'low-hanging fruit' dediğimiz basit botları ve kaba kuvvet saldırılarını engellemek için harika bir ilk hat. Ama o kadar. Gerçek bir güvenlik mimarisi için şu üçlü şart:

  1. Input Validation (Girdi Doğrulama): 'Kara liste' (Blacklist) mantığını bırakın. 'Sadece şu karakterlere izin ver' (Whitelist) mantığına geçin. Eğer bir kullanıcı adı sadece harf ve rakamdan oluşmalıysa, içinde % veya ' olan her şeyi daha uygulama katmanına girmeden reddedin.
  2. Context-Aware Output Encoding: Veriyi ekrana basarken nerede bastığınız çok önemli. HTML içinde mi, bir JavaScript değişkeninin içinde mi, yoksa bir URL parametresinde mi? Her birinin kaçış (escape) mekanizması farklıdır.
  3. Parameterized Queries: SQL Injection hala 1 numara. Neden? Çünkü hala 'string concatenation' ile sorgu yazanlar var. WAF bunu engellemeye çalışırken performansı düşürür, siz kodda Prepared Statements kullanırsanız WAF'a ihtiyacınız bile kalmaz.
# YANLIŞ: SQL Injection'a davetiye (testCompany örneği)
# query = "SELECT * FROM users WHERE username = '" + user_input + "'"

# DOĞRU: Parametreli Sorgu
query = "SELECT * FROM users WHERE username = %s"
cursor.execute(query, (user_input,))

Red Teamer Gözüyle Son Not

Arkadaşlar, biz bir sisteme sızmaya çalışırken WAF'ı bir engel değil, sadece aşılması gereken bir bulmaca olarak görüyoruz. Eğer sisteminizi sadece bir donanım veya bulut servisiyle koruyabileceğinize inanıyorsanız, kendinizi kandırıyorsunuz demektir. Güvenlik bir ürün değil, bir süreçtir ve bu sürecin en zayıf halkası her zaman 'kodun nasıl olsa korunduğu' yanılgısıdır.

Kodunuza güvenin ama onu test etmeyi asla bırakmayın. Bir sonraki sefere, o çok güvendiğiniz API'ların nasıl 'unauthenticated' veri sızdırdığına değineceğiz. O zamana kadar, tül perdelerinizi değil, duvarlarınızı kontrol edin.

Stay secure, stay geek!

İlgili yazılar