Önceki dersimizde, verinin farklı uygulama katmanları (frontend, API, backend) arasında akarken geçtiği güven sınırlarını ve bu sınırlardaki örtük varsayımların nasıl istismar edilebileceğini inceledik. Bir katmanın, gelen veriyi kendinden önceki katmanın "doğru" bir şekilde işlediğine dair körü körüne güveninin, Express.js gibi framework'lerde bile nasıl güvenlik zafiyetlerine yol açabildiğini gördük. Bu ders, tam olarak bu noktadan devam ediyor ve katmanlar arasındaki veri dönüşümlerinin en hassas ve tehlikeli türlerinden birine odaklanıyor: kodlama (encoding) ve kod çözme (decoding).
Bu derste, sanitizasyon mekanizmalarının zayıf karnını oluşturan kodlama/çözme sırası uyumsuzluklarını ve bir saldırganın bu durumu kullanarak güvenlik filtrelerini nasıl atlatabileceğini keşfedeceğiz. Çift kodlama (double encoding) gibi tekniklerin mantığını kavrayacak ve kod analizi sırasında bu tür zafiyetlere yol açan desenleri nasıl tespit edeceğinizi öğreneceksiniz.
Temel Prensip: "Önce Normalleştir, Sonra Temizle"
Veri güvenliğinin temel bir prensibi, veriyi işleyeceğiniz nihai (kanonik) formuna getirdikten sonra güvenlik kontrollerini uygulamaktır. Kod çözme, bu "normalleştirme" sürecinin en kritik adımlarından biridir. Bir güvenlik filtresi, verinin kodlanmış (encoded) hali üzerinde çalışırsa, bir sonraki katmanda kod çözüldüğünde ortaya çıkacak olan tehlikeli içeriği göremez. Bu durum, "işlem sırası uyumsuzluğu" olarak adlandırılır ve en inatçı güvenlik açıklarının temel nedenlerinden biridir.
Klasik hatalı sıra şöyledir:
- Girdi Alınır: Saldırgan, tehlikeli payload'ı (
<script>) kodlayarak gönderir (örneğin, URL kodlaması ile%3Cscript%3E). - Temizleme (Yanlış Adım): Bir Web Application Firewall (WAF) veya bir middleware, gelen
%3Cscript%3Emetnine bakar. Kendi kurallarında<script>ifadesini aradığı için bir tehdit görmez ve isteğin geçmesine izin verir. - Kod Çözme (Normalleştirme): Backend'deki web framework'ü (örn. Spring, Django, Express), gelen parametreyi otomatik olarak URL-decode eder.
%3Cscript%3Eartık orijinal hali olan<script>'e dönüşür. - Hedefe Ulaşma (Sink): Temizlenmemiş olan bu
<script>verisi, HTML sayfasına basılır ve Cross-Site Scripting (XSS) zafiyeti tetiklenir.
Buradaki temel sorun, temizleme işleminin, verinin nihai hedefe ulaşacağı formunu dikkate almadan, geçici ve kodlanmış bir form üzerinde yapılmasıdır.
Saldırganın Araç Kutusu: Gizleme (Obfuscation) Teknikleri
Saldırganlar, bu türden zayıf filtreleri atlatmak için çeşitli kodlama ve gizleme teknikleri kullanırlar. Bir kod analisti olarak bu tekniklere aşina olmanız, kodda "Neden burada base64 decode yapılıyor?" veya "Bu Unicode escape'ler nereden geliyor?" gibi sorular sormanızı sağlar.
Aşağıdaki tablo, yaygın olarak kullanılan bazı gizleme tekniklerini ve amaçlarını özetlemektedir.

Sanitizasyon Atlatma Teknikleri ve Çift Kodlama
Şimdi, bu teorik bilgiyi pratiğe dökelim. Privia Security tarafından hazırlanan makale, blacklist tabanlı basit filtrelerin çeşitli kodlama teknikleriyle nasıl aşılabileceğini somut örneklerle gösteriyor.
Derinlemesine XSS Saldırı Teknikleri – Kimlik Bilgisi Yakalama
Bu makale, XSS filtrelerini atlatmak için kullanılan yaratıcı yöntemleri inceliyor. Özellikle, kodlama ve etiket manipülasyonunun basit güvenlik önlemlerini nasıl etkisiz hale getirebileceğine odaklanacağız.
Makalede "XSS Güvenlik Önlemlerinin Atlatılması" başlığı altındaki iki ana bölümü inceleyin: Karakter Kodlama: Bu bölümde yer alan örnekleri dikkatle okuyun. Özellikle şu senaryolara odaklanın: javascript: URI şemasını engellemeye çalışan bir filtrenin, j harfinin ASCII (j) veya Hex (j) karşılığı kullanılarak nasıl aşıldığı. Tüm girdiyi büyük harfe çeviren (toUpperCase()) bir filtrenin, JavaScript'in büyük-küçük harf duyarlılığından faydalanılarak ve alert gibi fonksiyonların ASCII karakter kodlarıyla yazılarak nasıl atlatıldığı. Bu, kod çözme (tarayıcının ASCII'yi karaktere çevirmesi) işleminin, sanitizasyon (büyük harfe çevirme) işleminden sonra etkili olduğu klasik bir sıra uyumsuzluğudur. Base64 ve Unicode kodlamalarının filtreleri tamamen nasıl devre dışı bırakabildiğini inceleyin. HTML Etiketlerinin Manipüle Edilmesi: Bu bölümde sunulan teknikleri analiz edin. Şu desenler özellikle önemlidir: <script> etiketini silen bir filtrenin, <scr<script>ipt> gibi iç içe bir yapı kullanılarak nasıl kandırıldığı. Filtre, ortadaki <script>'i sildiğinde, geriye kalan parçalar birleşerek tekrar geçerli bir etiket oluşturur. Bu, "recursive" veya "nested" atlatma tekniğinin basit bir örneğidir. Etiket adı ve özellikler arasındaki boşlukları kontrol eden bir filtrenin, HTML'nin esnekliği sayesinde / karakteri kullanılarak nasıl aşıldığı (<img/src=...). Bu örnekler, bir güvenlik filtresi yazmanın ne kadar zor olduğunu ve saldırganların veriyi yorumlayan parser'ın (bu durumda tarayıcının HTML/JS motoru) kurallarını, filtreyi yazan geliştiriciden daha iyi bildiğinde neler yapabileceğini göstermektedir.
Bağlam Uyumsuzluğu: HTML vs. JavaScript
Kodlama/çözme uyumsuzluklarının en tehlikeli türlerinden biri, verinin bir bağlam için güvenli hale getirilirken, başka bir bağlamda güvensiz hale gelmesidir. En klasik örnek, sunucudan gelen verinin bir HTML sayfasındaki <script> bloğu içine yerleştirilmesidir.
Geliştirici, XSS'i önlemek için geleneksel HTML encoding uygulayabilir (örn. > karakterini > yapmak). Ancak bu, JavaScript string'i bağlamında tamamen anlamsızdır.

Kod analizi yaparken, verinin yerleştirildiği nihai bağlamı (HTML body, HTML attribute, JavaScript string, CSS URL, vb.) tespit etmek ve uygulanan sanitizasyonun o bağlama uygun olup olmadığını doğrulamak zorundasınız. Bağlama uygun olmayan her sanitizasyon, potansiyel bir zafiyettir.
Parser Farklılıkları: Sadece Web'in Ötesinde
Bu kodlama ve yorumlama farklılıkları sadece HTML ve JavaScript ile sınırlı değildir. Modern dağıtık sistemlerde, farklı teknolojilerle yazılmış servisler aynı veri formatlarını (JSON, XML, Protobuf vb.) işlerken, kullandıkları parser kütüphanelerinin nüanslarından kaynaklanan ciddi zafiyetler ortaya çıkabilir. Bu konu, uzman seviyesinde bir kod analistinin mutlaka hakim olması gereken bir alandır.
Mehmet İnce'nin "2021 Yılının En Önemli 10 Web Hacking Teknikleri" videosundan iki ileri seviye örnekle bu konuyu derinleştirelim.
2021 Yılının En Önemli 10 Web Hacking Teknikleri
Bu video, modern sistemlerde karşılaşılan ve basit string eşleştirmelerinin ötesine geçen karmaşık parser ve kod çözme zafiyetlerini ele alıyor.
Lütfen aşağıdaki bölümleri dikkatle izleyin: JSON Parser Farklılıkları: Bu bölümde, aynı JSON nesnesindeki tekrar eden anahtarların ({"key": "A", "key": "B"}) farklı parser'lar tarafından nasıl farklı yorumlanabileceği anlatılıyor. Örneğin, bir proxy veya frontend servisi ilk değeri (A) baz alarak bir güvenlik kontrolü yaparken, asıl işi yapan backend servisi son değeri (B) işleyebilir. Bu, sanitizasyonun (veya iş mantığı kontrolünün) verinin yanlış bir versiyonu üzerinde yapılmasına neden olan klasik bir "parser differential" (parser farklılığı) sorunudur. Arşiv Dosyası Olarak Payload (Path Traversal): Bu kısımda anlatılan cdnjs zafiyeti, kodlama/çözme sorunlarının en etkili örneklerinden biridir. Burada: "Kodlanmış" Veri: Kullanıcının yüklediği .tar.gz arşivi. "Kod Çözme" İşlemi: Sunucunun bu arşivi açması (decompress/extract). Zafiyet: Arşiv içindeki dosya adları (../evil.sh) sunucu tarafından doğrulanmıyor (sanitize edilmiyor). Dosya sistemi, bu "kod çözülmüş" yolu yorumlayarak, beklenmedik bir dizine dosya yazılmasına (Path Traversal) neden oluyor. Bu vaka, "kodlama" kavramının sadece base64 veya URL encoding gibi string dönüşümleri olmadığını; bir dosya formatının kendisinin de bir "kodlama" katmanı olarak düşünülebileceğini ve bu katmanın açıldığı her yerin kritik bir güvenlik kontrol noktası olduğunu gösterir.
Sonuç
Bu derste, sanitizasyon atlatmanın temelindeki mantığı, yani kodlama ve kod çözme işlemlerinin sırası ve bağlamı üzerine odaklandık. Gördük ki, bir güvenlik kontrolünün etkinliği, sadece var olup olmadığına değil, veri akışının neresinde ve hangi veri formu üzerinde çalıştığına bağlıdır.
Temel Çıkarımlar:
- Sıra Kritik Öneme Sahiptir: Güvenlik kontrolleri (sanitizasyon, validasyon) daima veri nihai formuna (tamamen çözülmüş ve normalleştirilmiş) ulaştıktan sonra ve kullanılacağı hedeften hemen önce uygulanmalıdır.
- Bağlam Kraldır: Bir veri için uygulanan kodlama/temizleme yöntemi, verinin yerleştirileceği nihai bağlama (HTML, JS, SQL, dosya yolu vb.) uygun olmalıdır. Tek bir çözüm her duruma uymaz.
- Parser'lar Farklı Düşünür: Farklı katmanlarda veya servislerde farklı parser kütüphaneleri kullanılıyorsa, bunların aynı veriyi farklı yorumlama potansiyelini (örn. tekrar eden JSON anahtarları, XML yorumları) bir risk faktörü olarak değerlendirin.
- Kodlama Her Yerdedir: Kodlama sadece string manipülasyonu değildir. Dosya formatları (zip, tar), serileştirme formatları (Java serialization, Pickle) ve karmaşık protokoller (SAML) de birer kodlama katmanıdır ve bu katmanlar açıldığında ortaya çıkan veri mutlaka doğrulanmalıdır.
Bu dersle birlikte, manuel taint analizi yeteneklerinizi bir üst seviyeye taşıdınız. Artık sadece bir verinin akışını değil, o akış sırasında geçirdiği dönüşümleri ve bu dönüşümlerin yarattığı güvenlik risklerini de analiz edebiliyorsunuz.
Gelecek dersten itibaren yeni bir modüle geçiyoruz: Kimlik Doğrulama ve Oturum Yönetimi. Veri manipülasyonu konusundaki bu derin bilgimizle, şimdi bir uygulamanın giriş kapısı olan kimlik doğrulama mekanizmalarındaki mantık hatalarını, geri dönüş yollarını ve hata durumlarını istismar ederek bu kapıyı nasıl atlayabileceğimizi inceleyeceğiz.