url içinde çift kaçış dizisi: İstek filtreleme modülü, çift kaçış dizisi içeren bir isteği reddedecek şekilde yapılandırılmıştır


86

ASP.NET MVC uygulamamda aşağıdaki gibi bir URL uygulamaya çalışıyorum:

/ ürün / etiketler / + aileler için

Uygulamamı varsayılan yapılandırmalarla çalıştırmayı denediğimde, şu mesajı 404.11 Yanıt Kodu ile alıyorum:

HTTP Hatası 404.11 - Bulunamadı

İstek filtreleme modülü, çift kaçış dizisi içeren bir isteği reddedecek şekilde yapılandırılmıştır.

Aşağıdaki kodu web.config dosyamın içine uygulayarak bu hatayı çözebilirim:

  <system.webServer>
    <security>
      <requestFiltering allowDoubleEscaping="true" />
    </security>
  </system.webServer>

Yani, şimdi hiç alamıyorum 404.11.

Merak ettiğim bu uygulama ile ne tür güvenlik açıkları açıyorum.

BTW, uygulamam altında .Net Framework 4.0ve çalışıyor IIS 7.5.


/product/tags/for%20familiesBunun yerine kullanarak istenilen kaynağa ulaşmak mümkün müdür ? Ardından boşluk içeren kimlikler için bir geçici çözümünüz var. Yoksa tamamen burada mıyım?
Anders Tornblad

@atornblad biraz kapalı sanırım. Sorum: Merak ettiğim bu uygulama ile ne tür güvenlik açıkları açıyorum.
tugberk

Yanıtlar:


57

Açabileceğiniz güvenlik açıkları, kod enjeksiyonu ile ilgilidir - HTML enjeksiyonu, JavaScript enjeksiyonu veya SQL enjeksiyonu.

Varsayılan ayarlar, yaygın enjeksiyon stratejilerinin çalışmasına izin vermeyerek sizi saldırılardan yarı verimli bir şekilde korur. Ne kadar fazla varsayılan güvenlik kaldırırsanız, URL'ler, GET istek sorgu dizeleri, POST istek verileri, HTTP üstbilgileri vb. Aracılığıyla sağlanan girdilerle ne yapacağınızı o kadar çok düşünmeniz gerekir ...

Örneğin, ideylem yönteminizin parametresine dayalı olarak dinamik SQL sorguları oluşturuyorsanız , aşağıdaki gibi:

public ActionResult Tags(string id)
{
    var sql = "SELECT * FROM Tags Where tagName = '" + id + "'";
    // DO STUFF...
}

(... bu iyi bir fikir DEĞİLDİR ), .NET çerçevesi tarafından uygulanan varsayılan koruma, bu URL'yi isteyen kullanıcı gibi daha tehlikeli bazı senaryoları durdurabilir:

/product/tags/1%27;drop%20table%20Tags;%20--

Tüm fikir, url'lerin her bölümünü ve eylem yöntemlerine yönelik diğer girdileri olası tehditler olarak ele almaktır. Varsayılan güvenlik ayarı, bu korumanın bir kısmını sizin için sağlar. Değiştirdiğiniz her varsayılan güvenlik ayarı, manuel olarak işlemeniz gereken biraz daha fazla potansiyel kötülük için açılır.

Bu şekilde SQL sorguları oluşturmadığınızı varsayıyorum. Ancak, kullanıcı girişini veritabanınızda sakladığınızda ve daha sonra bunları görüntülediğinizde daha sinsi şeyler gelir. Kötü niyetli kullanıcı, veritabanınızda kodlanmamış olarak çıkan JavaScript veya HTML depolayabilir ve bu da sisteminizin diğer kullanıcılarını tehdit edebilir.


6

Güvenlik riski

Ayar allowDoubleEscapingyalnızca path(cs-uri-stem) için geçerlidir ve en iyi OWASP Çift Kodlama ile açıklanır . Teknik, isteği iki kez URL Kodlama ile güvenlik kontrollerini aşmak için kullanılır. URL'nizi örnek olarak kullanarak:

/product/tags/for+families --> /product/tags/for%2Bfamilies --> /product/tags/for%252Bfamilies

Özel olarak için güvenlik kontrolleri olduğunu varsayalım /product/tags/for+families. /product/tags/for%252BfamiliesAynı kaynak olan ancak yukarıda belirtilen güvenlik kontrolleri tarafından kontrol edilmeyen bir istek gelir . Genelleştirilmiş güvenlik kontrolleri terimini kullandım çünkü bunlar kimliği doğrulanmış bir kullanıcı gerektirme, SQLi'yi kontrol etme vb. Gibi herhangi bir şey olabilir.

IIS Neden Engelliyor?

Artı işareti (+), RFC2396'ya göre ayrılmış bir karakterdir :

Çoğu URI, belirli özel karakterlerden oluşan veya bunlarla sınırlandırılmış bileşenler içerir. Bu karakterler, URI bileşenindeki kullanımları ayrılmış amaçlarıyla sınırlı olduğundan "ayrılmış" olarak adlandırılır. Bir URI bileşenine ilişkin veriler ayrılmış amaç ile çelişiyorsa, URI oluşturmadan önce çakışan verilerden çıkış yapılmalıdır.

  reserved    = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
                "$" | ","

Wade Hilmo'nun, IIS'nin URL'lerdeki karakterleri nasıl engellediği başlıklı mükemmel bir yazısı var . Sağlanan birçok bilgi ve arka plan var. Artı işaretine özel bölüm şu şekildedir:

Bu yüzden allowDoubleEscaping / VerifyNormalization oldukça basit görünüyor. Neden kafa karışıklığına neden olduğunu söyledim? Sorun, bir URL'de '+' karakterinin görünmesidir. "+" Karakteri, "%" içermediğinden, kaçmış görünmüyor. Ayrıca, RFC 2396 bunu, çıkış yapılmış biçimde (% 2b) bir URL'ye dahil edilebilecek ayrılmış bir karakter olarak not eder. Ancak allowDoubleEscaping varsayılan değeri false değerine ayarlandığında, onu kaçmış biçimde bile engelleyeceğiz. Bunun nedeni tarihseldir: HTTP'nin ilk günlerinde, '+' karakteri bir boşluk karakteri için kısaltma olarak kabul edildi. Bazı standartlaştırıcılar, '+' içeren bir URL verildiğinde, onu bir alana dönüştürür. Bu nedenle, bir URL'de "+" nın standart dışı olduğunu kabul ediyoruz. Bu '+' tedavisini çağıran bir RFC'ye herhangi bir referans bulamadım,

Kendi deneyimlerime göre, IIS günlüğe kaydettiğinde istek alanlarının artı işaretiyle değiştirildiğini biliyorum. Adda artı işaretinin olması, günlükleri ayrıştırırken kafa karışıklığına neden olabilir.

Çözüm

Bunu düzeltmenin üç yolu ve artı işaretini kullanmanın iki yolu vardır.

  1. allowDoubleEscaping=true- Bu, tüm web siteniz / uygulamanız için çift kaçışa izin verecektir. İçeriğe bağlı olarak, bu en hafif tabirle istenmeyen bir durum olabilir. Aşağıdaki komut ayarlanacaktır allowDoubleEscaping=true.

    appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /allowDoubleEscaping:True
    
  2. alwaysAllowedUrls- İstek Filtreleme, beyaz liste yaklaşımı sunar. Bu URL yolunu alwaysAllowedUrls'a eklediğinizde, istek diğer İstek Filtreleme ayarlarıyla kontrol edilmeyecek ve IIS istek kanalında devam edecektir. Buradaki endişe, İstek Filtreleme'nin aşağıdakiler için isteği kontrol etmemesidir:

    • İstek Sınırları: maxContentLength, maxUrl, maxQueryString
    • Fiiller
    • Sorgu - sorgu dizesi parametreleri kontrol edilmeyecek
    • Çift Kaçış
    • Yüksek Bit Karakterler
    • Filtreleme Kuralları İste
    • Üstbilgi Sınırları İste

    Aşağıdaki komut katacak /product/tags/for+familiesiçin alwaysAllowedUrlsVarsayılan Web sitesi üzerinde.

    appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"alwaysAllowedUrls.[url='/product/tags/for+families']"
    
  3. Yeniden adlandır - evet, sadece dosyayı / klasörü / denetleyiciyi / vb. Yeniden adlandırın. Eğer mümkünse. Bu en kolay çözümdür.


IIS Express ile geliştirme sırasında DoubleEscaping'e izin vermek için işte yaptığım şey: stackoverflow.com/q/56463044/381082
DeveloperDan

5

Bunun için etrafta bir çalışma yaptım. yani kodlanmış dizeyi (IIS) URL'sinin içine koymak istediğinizde, onu kirli olanlardan temizlemeniz gerekir: {";", "/", "?", ":", "@", "&", " = "," + "," $ ",", "}; ve onu deşifre etmek ve tekrar kullanmak istediğinizde, onu çözmeden önce yeniden kirletmeniz gerekir (istenen sonucu elde etmek için).

İşte kodum, umarım birine yardımcı olur:

 public static string cleanUpEncription(string encriptedstring)
        {
            string[] dirtyCharacters = { ";", "/", "?", ":", "@", "&", "=", "+", "$", "," };
            string[] cleanCharacters = { "p2n3t4G5l6m","s1l2a3s4h","q1e2st3i4o5n" ,"T22p14nt2s", "a9t" , "a2n3nd","e1q2ua88l","p22l33u1ws","d0l1ar5","c0m8a1a"};

            foreach (string dirtyCharacter in dirtyCharacters)
            {
                encriptedstring=encriptedstring.Replace(dirtyCharacter, cleanCharacters[Array.IndexOf(dirtyCharacters, dirtyCharacter)]);
            }
            return encriptedstring;
        }

        public static string MakeItDirtyAgain(string encriptedString)
        {
            string[] dirtyCharacters = { ";", "/", "?", ":", "@", "&", "=", "+", "$", "," };
            string[] cleanCharacters = { "p2n3t4G5l6m", "s1l2a3s4h", "q1e2st3i4o5n", "T22p14nt2s", "a9t", "a2n3nd", "e1q2ua88l", "p22l33u1ws", "d0l1ar5", "c0m8a1a" };
            foreach (string symbol in cleanCharacters)
            {
                encriptedString = encriptedString.Replace(symbol, dirtyCharacters[Array.IndexOf(cleanCharacters,symbol)]);
            }
            return encriptedString;
        }

PntGlm nedir?
StuperUser

@StuperUser sadece rastgele karakterler
Mark Dibeh

1
base64Bu ikame tekniğini kullanmak yerine dize kodlanmalıdır. Örneğin, Temel Kimlik Doğrulama, base64özel / ayrılmış karakterler içerebileceğinden gönderilen kimlik bilgilerini kodlamak için kullanır .
user2320464

base64 ile ilgili sorun bir base64 karakteridir ve rotaları bozabilir
Garr Godfrey

1

Bu yüzden bir MVC uygulamasından bir API çağırırken bununla karşılaştım. Güvenlik deliğini açmak yerine yolumu değiştirdim.

Öncelikle, bu ayarı DEVRE DIŞI BIRAKMAYINIZ. Uygulamanın / kaynağın tasarımını değiştirmek daha uygundur (örneğin yolu kodlamak, verileri bir başlıkta veya gövdede geçirmek).

Bu daha eski bir gönderi olmasına rağmen , System.Web'de HttpUtility.UrlPathEncode yöntemini kullanarak bunu bir API'ye yapılan bir çağrıdan alıyorsanız bu hatayı nasıl çözebileceğinizi paylaşacağımı düşündüm .

Çağrı yapmak için RestSharp kullanıyorum , bu yüzden benim örneğim RestRequest'i kullanıyor:

var tags = new[] { "for", "family" };
var apiRequest = new RestRequest($"product/tags/{HttpUtility.UrlPathEncode(string.Join("+", tags))}");

Bu şuna eşit bir yol oluşturur:

/ product / tags / for% 2Bfamilies

Başka bir notta, bir kullanıcının girdilerine dayalı dinamik bir sorgu OLUŞTURMAYIN. Her zaman bir SqlParameter kullanmalısınız . Ayrıca, enjeksiyon saldırılarını önlemek için değerleri uygun kodlamayla döndürmek güvenlik açısından son derece önemlidir.

~ Şerefe


0

Şifrelenmiş dizeyi ayrı ayrı kodlayın:

return HttpServerUtility.UrlTokenEncode(Encoding.UTF8.GetBytes("string"));

Ayrılan şifrelenmiş dizenin kodunu çözün:

string x = Encoding.UTF8.GetString(HttpServerUtility.UrlTokenDecode(id));
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.