Bir güvenlik açığını düzeltmeden önce yan etkilerini anlamamak, başka bir açığı açabilir. Son makalemde URL kodlaması hakkında ve neden PHP güvenlik kontrollerinin sıklıkla kodlanmış saldırı yüklerini gözden kaçırdığı üzerinde durdum. Bir geliştirici bunu okuyarak, dikkatle araştırılması gereken bir soru sordu.
<p>“Eğer bir urldecode() iki katlı kodlamada yeniliyorsa, değişmediği sürece decode işlemini döngüye almak mantıklı görünüyor — ama bu, bir saldırganın CPU kaynaklarını tüketmek için derinlemesine iç içe geçmiş kodlama göndermesine neden olan bir decode bombası açar mı?”</p>
<p>Bu, derinlemesine incelenmeye değer, geçerli bir endişedir.</p>
<p>“Decode Bombası” ile Ne Demek İstiyorum</p>
<p>Decode bombası terimi, bir saldırganın özel olarak her istekte sunucunuzun aşırı şekilde decoding yapılmasını sağlamayı amaçlayan derinlemesine iç içe geçmiş URL kodlamasıyla bir istek oluşturması senaryosunu tanımlamak için kullanıyorum. Bu, bir ZIP bombasına benzer; küçük bir sıkıştırılmış dosyanın devasa bir dosyaya genişlemesi gibi ama dosya açma yerine URL decode işlemi için geçerlidir. Bu, yaygın olarak standart bir güvenlik terimi olmasa da, tarif ettiği desen gerçektir. Uygulamada nasıl çalıştığı şöyle: Eğer kodunuz urldecode() işlemini, dize değişmeyi durdurana kadar döngüye alıyorsa, bir saldırgan derinlemesine iç içe geçmiş bir kodlama yükü gönderebilir.</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>%25252525252527
<p>Her geçişte ne olur:<br/></p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>Pass 1: %25252525252527 → %252525252527
Pass 2: %252525252527 → %2525252527
Pass 3: %2525252527 → %25252527
Pass 4: %25252527 → %252527
Pass 5: %252527 → %2527
Pass 6: %2527 → %27
Pass 7: %27 → ‘
<p>Bir karakteri decode etmek için yedi geçiş. Sunucunuz, her istek başına gereksiz yer açma işlemleri gerçekleştiriyor. Uygulamanızdan bağımsız olarak, tek bir isteğin sorun yaratması olası değildir; ancak aşırı decoding işlemi gerçekleştiren bir kod üzerinde tekrar eden istekler, CPU kaynağını gereksiz yere tüketebilir. Kodu düzeltmiş olabilirsiniz, ama aynı satırda bir kaynak sorunu açmış olabilirsiniz.</p>
<p>Bu Kolayca Gözden Kaçabilir</p>
<p>Bu tür bir güvenlik açığı, standart penetrasyon testlerinde ortaya çıkmaz. Bunun yerine, üretimde birisi sunucusunun alışılmadık trafik kalıpları altında beklenenden daha yavaş çalıştığını fark ettiğinde keşfedilir. Saldırganın veri çıkarmasına gerek yoktur; kimlik doğrulamasını aşmasına gerek yoktur. Tek ihtiyacı olan şey, sunucunuzun meşru kullanıcılarından daha uzun süre işlem yapmasını sağlamaktır.</p>
<p>Bir tek geliştirici ya da sınırlı sunucu kaynaklarına sahip küçük bir ajans için, bu tür alışılmadık trafik kalıpları sürekli olduğunda, performans belirgin şekilde kötüleşebilir.</p>
<p>Güvenli Çözüm: Decode Geçişlerini Sınırlandırın</p>
<p>Düzeltme, belirli bir karara bağlıdır: maksimum bir decode sayısı seçin ve asla aşmayın.</p>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code>$query = $_SERVER['QUERY_STRING'] ?? '';
$maxPasses = 3;
$i = 0;
$previous = null;
while ($previous !== $query && $i < $maxPasses) {
$previous = $query;
$query = urldecode($query);
$i++;
}
$query = strtolower($query);
<p>Üç geçiş, birçok uygulama için makul bir üst sınırdır, ancak doğru sınır mimarinize, çerçevenize ve tehdit modelinize bağlıdır. Döngü, dize değişmeyi durdurursa da erken durur, böylece tek katlı kodlama yalnızca bir geçiş yapar, üç değil.</p>
<p>Tek katlı kodlama, en yaygın saldırı kaçış tekniğidir. İki katlı kodlama bir sonraki katmandır. Daha derin iç içe kodlama, web sunucunuzun, ters proxy’nin veya PHP çerçevenizin, başvuru uygulama kodunuza ulaşmadan önce zaten üstteki kodlamayı işlemesi gereken bir alandadır.</p>
<p>Bu eklentiyi eklemeden Önce</p>
<p>Uygulamanıza özel decoding mantığı eklemeden önce, web sunucunuzun, ters proxy’nizin, çerçevenizin ve PHP’nin zaten gelen istekleri nasıl normalleştirdiğini anlamalısınız. Birden fazla decode katmanı, hem güvenlik hem de doğruluk sorunları ortaya çıkarabilir.</p>
<p>Laravel kullanıyorsanız, istek verilerinin çeşitli şekillerde normalleştirildiğini unutmayın. Ek bir decode katmanı eklemeden önce, URL decoding'in nerede zaten gerçekleştiğini anlamaya çalışın.</p>
<p>Normalizasyon kodu eklemeden önce tüm istek yığınınızı anlamalısınız.</p>
<p>Desen Eşleştirmenin Sınırları</p>
<p>URL decoding’i sınırlandırmış olsanız bile, desen eşleştirmenin temel bir zayıflığı vardır: yalnızca bakmayı bildiğiniz şeyleri yakalar.</p>
<p>Saldırganlar, bilinen desenleri aşmak için özel olarak tasarlanmış yeni yükler oluşturuyorlar. Alternatif sözdizimi kullanıyorlar. Veritabanına özgü kodlama kullanıyorlar. Anahtar kelimeleri parçalara ayırmak için yorumları kullanıyorlar.</p>
<div class="highlight js-code-highlight">
<pre class="highlight sql"><code>SE/*comment*/LECT * FR/*comment*/OM users
<p>Desen eşleştirmeniz seçimi arar. Sürekli bir dize olarak asla gözükmez. Kontrol geçebilir. Saldırının başarısı, uygulama girişini nasıl işlediğine bağlıdır.</p>
<p>Bu, imza tabanlı tespitin temel sınırlamasıdır: bilinen kötü desenleri yakalar. Bilinmeyenleri atlar.</p>
<p>Daha Geniş Ders: Her Güvenlik Düzeltmesinin Yan Etkileri Vardır</p>
<p>Bu, çoğu güvenlik eğitiminin atladığı kısımdır.</p>
<p>Bir güvenlik kontrolü eklediğinizde, yalnızca bir kapıyı kapatmıyorsunuz. Aynı zamanda başka bir kapının açılmasına neden oluyorsunuz. Her güvenlik düzeltmesinden sonra sorulması gereken soru yalnızca “bu, endişelendiğim saldırıyı durdurur mu?” değil, “bu, önceden endişe duymadığım neyi mümkün kılıyor?” olmalıdır.</p>
<p>Sınırsız URL decoding, kodlama tabanlı kaçışı durdurur. Bu, kaynak tükenmesi riskini beraberinde getirir.</p>
<p>Sınırlandırılmış URL decoding, çoğu kodlama tabanlı kaçışı azaltır. Bu, CPU maruziyetini sınırlar ve üst akış altyapısının zaten ele alması gereken derinlemesine iç içe kodlamayı kaçırır.</p>
<p>Her güvenlik kararı bir takas işlemidir. Takası anlamak, güvenlik gösterisi ekleyen bir geliştirici ile gerçek savunma oluşturan bir geliştirici arasındaki farkı ayırır.</p>
<p>Tespit vs Önleme</p>
<p>Şu ana kadar yazdığım makalelerin her biri, şüpheli istekleri kaydetme, girdi normalleştirme, davranışsal sinyalleri tanıma üzerinedir.</p>
<p>Tespit değerlidir. Ama bir üst sınırı vardır.</p>
<p>SQL injection için gerçek düzeltme, sorgu katmanında yaşar, tespit katmanında değil. Parametreli sorgular, bu sorgu için SQL injection'ı yapı olarak imkansız kılar, bunun etrafında hiçbir kodlama numarası etkili olamaz.</p>
<p>Tespit size şüpheli bir şeyin olduğunu bildirir. Önleme, bunun önemli olmasını durdurur.</p>
<p>En güçlü güvenlik duruşu her ikisini de kullanır:</p>
<p>Önleme: parametreli sorgular, girdi doğrulama, çıktı kodlama, uygun kimlik doğrulama<br/>
Tespit: normalleşmiş desen eşleştirme, davranışsal anomali tespiti, yanıt boyutu izleme, gerçek zamanlı alarm verme<br/>
Hiçbiri diğerinin yerini almaz. Önleme, saldırı yüzeyinizi azaltır. Tespit, önlemenin atladığını kaplar.</p>
<p>Kriosa'nın Arkasındaki Yönelim</p>
<p>Kriosa'nın tasarım prensiplerinden biri, नियंत्रित girdi normalizasyonu, normalizasyonu öngörülebilir, sınırlı tutmak ve yalnızca tekrarlı decode işlemine dayanmak yerine davranışsal analizle birleştirmektir.</p>
<p>XAI paneli daha sonra nelerin tespit edildiğini ve nedenini açıklar, böylece saldırı desenini sadece bir şeyin engellendiği değil, bu saldırganın neyi başarmak istediğini de anlama şansı bulursunuz.</p>
<p>Bu, bir günlük filtre ile bir güvenlik katmanı arasındaki farktır. Bir tanesi size bir şeyin şüpheli göründüğünü söyler. Diğeriyse bunun ne olduğunu, neden işaretlendiğini ve saldırganın neyi başarmaya çalıştığını size söyler.</p>