W mojej aplikacji ASP.NET MVC próbuję zaimplementować adres URL, jak poniżej:
/ produkt / tagi / dla + rodzin
Kiedy próbuję uruchomić aplikację z domyślnymi konfiguracjami, otrzymuję ten komunikat z kodem odpowiedzi 404.11:
Błąd HTTP 404.11 - Nie znaleziono
Moduł filtrowania żądań jest skonfigurowany tak, aby odrzucać żądanie zawierające podwójną sekwencję ucieczki.
Mogę obejść ten błąd, implementując poniższy kod w moim web.config:
<system.webServer>
<security>
<requestFiltering allowDoubleEscaping="true" />
</security>
</system.webServer>
Więc teraz nie dostaję żadnego 404.11
.
Zastanawiam się, jakie rodzaje luk w zabezpieczeniach otwieram w tej implementacji.
A tak przy okazji, moja aplikacja jest .Net Framework 4.0
uruchomiona i działa pod IIS 7.5
.
asp.net
asp.net-mvc
asp.net-mvc-3
iis
iis-7
tugberk
źródło
źródło
/product/tags/for%20families
zamiast tego dotrzeć do żądanego zasobu ? Następnie masz obejście dla identyfikatorów zawierających spacje. A może jestem tutaj całkowicie wyłączony?Odpowiedzi:
Luki bezpieczeństwa, które możesz otworzyć, mają związek z wstrzyknięciem kodu - wstrzyknięciem HTML, wstrzyknięciem JavaScript lub wstrzyknięciem SQL.
Domyślne ustawienia chronią Cię przed atakami pół wydajnie, uniemożliwiając działanie typowych strategii wstrzykiwania. Im więcej domyślnych zabezpieczeń usuwasz, tym więcej musisz myśleć o tym, co robisz z danymi wejściowymi dostarczanymi przez adresy URL, kwerendy żądań GET, dane żądań POST, nagłówki HTTP i tak dalej ...
Na przykład, jeśli tworzysz dynamiczne zapytania SQL na podstawie
id
parametru Twojej metody akcji, na przykład:public ActionResult Tags(string id) { var sql = "SELECT * FROM Tags Where tagName = '" + id + "'"; // DO STUFF... }
(... co NIE jest dobrym pomysłem), domyślna ochrona, wprowadzona przez platformę .NET, może powstrzymać niektóre z bardziej niebezpiecznych scenariuszy, takich jak użytkownik żądający tego adresu URL:
/product/tags/1%27;drop%20table%20Tags;%20--
Cała idea polega na traktowaniu każdej części adresów URL i innych danych wejściowych do metod działania jako możliwych zagrożeń. Domyślne ustawienie zabezpieczeń zapewnia część tej ochrony. Każde domyślne ustawienie zabezpieczeń, które zmieniasz, otwiera się na nieco więcej potencjalnych zagrożeń, z którymi musisz sobie poradzić ręcznie.
Zakładam, że nie tworzysz zapytań SQL w ten sposób. Ale bardziej podstępne rzeczy pojawiają się, gdy przechowujesz dane wejściowe użytkownika w swojej bazie danych, a następnie wyświetlasz je. Zły użytkownik może przechowywać JavaScript lub HTML w twojej bazie danych, które wyjdą niezakodowane, co z kolei zagrozi innym użytkownikom twojego systemu.
źródło
Zagrożenie dla bezpieczeństwa
To ustawienie
allowDoubleEscaping
ma zastosowanie tylko dopath
(cs-uri-stem) i najlepiej jest wyjaśnione przez podwójne kodowanie OWASP . Technika ta służy do obejścia kontroli bezpieczeństwa poprzez dwukrotne kodowanie adresu URL żądania. Na przykładzie adresu URL:/product/tags/for+families --> /product/tags/for%2Bfamilies --> /product/tags/for%252Bfamilies
Załóżmy, że istnieją mechanizmy zabezpieczeń specjalnie dla
/product/tags/for+families
. Nadchodzi żądanie, dla/product/tags/for%252Bfamilies
którego jest to ten sam zasób, ale nie jest ono sprawdzane przez wyżej wymienione mechanizmy bezpieczeństwa. Użyłem uogólnionego terminu kontroli bezpieczeństwa, ponieważ może to być wszystko, na przykład wymaganie uwierzytelnionego użytkownika, sprawdzanie SQLi itp.Dlaczego usługi IIS blokują?
Znak plus (+) jest znakiem zastrzeżonym zgodnie z RFC2396 :
Wade Hilmo ma doskonały post zatytułowany Jak IIS blokuje znaki w adresach URL . Podano wiele informacji i tła. Część dotycząca znaku plus jest następująca:
Z własnego doświadczenia wiem, że w logach IIS spacje żądań są zastępowane znakiem plus. Posiadanie znaku plus w nazwie może powodować zamieszanie podczas analizowania dzienników.
Rozwiązanie
Istnieją trzy sposoby rozwiązania tego problemu i dwa sposoby, aby nadal używać znaku plus.
allowDoubleEscaping=true
- Pozwoli to na podwójną ucieczkę dla całej witryny / aplikacji. W zależności od treści może to być co najmniej niepożądane. Następujące polecenie zostanie ustawioneallowDoubleEscaping=true
.appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /allowDoubleEscaping:True
alwaysAllowedUrls
- Filtrowanie żądań oferuje podejście do białej listy. Dodając tę ścieżkę adresu URL do alwaysAllowedUrls, żądanie nie będzie sprawdzane przez żadne inne ustawienia filtrowania żądań i będzie kontynuowane w potoku żądań usług IIS. Problem polega na tym, że funkcja filtrowania żądań nie sprawdzi żądania pod kątem:Następujące polecenie zostanie dodane
/product/tags/for+families
doalwaysAllowedUrls
domyślnej witryny sieci Web.appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"alwaysAllowedUrls.[url='/product/tags/for+families']"
Zmień nazwę - tak, po prostu zmień nazwę pliku / folderu / kontrolera / itp. Jeśli to możliwe. To najłatwiejsze rozwiązanie.
źródło
Przygotowałem do tego robotę. więc kiedy chcesz umieścić zaszyfrowany ciąg wewnątrz adresu URL dla (IIS), musisz go wyczyścić z brudnych: {";", "/", "?", ":", "@", "&", " = "," + "," $ ",", "}; a kiedy chcesz go odszyfrować i użyć ponownie, musisz go ponownie zabrudzić przed odszyfrowaniem (aby uzyskać pożądany wynik).
Oto mój kod, mam nadzieję, że komuś pomoże:
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; }
źródło
base64
zakodowany zamiast korzystać z tej techniki zastępowania. Na przykład uwierzytelnianie podstawowe używabase64
do kodowania przesłanych poświadczeń, ponieważ mogą one zawierać znaki specjalne / zastrzeżone.Więc napotkałem to, gdy wywoływałem API z aplikacji MVC. Zamiast otwierać lukę w zabezpieczeniach, zmodyfikowałem ścieżkę.
Po pierwsze, NIE ZALECAM wyłączania tego ustawienia. Bardziej właściwe jest zmodyfikowanie projektu aplikacji / zasobu (np. Zakodowanie ścieżki, przekazanie danych w nagłówku lub w treści).
Chociaż jest to starszy post, pomyślałem, że podzielę się, w jaki sposób można rozwiązać ten błąd, jeśli otrzymujesz to z wywołania interfejsu API przy użyciu metody HttpUtility.UrlPathEncode w System.Web .
Używam RestSharp do wywoływania, więc mój przykład używa RestRequest:
var tags = new[] { "for", "family" }; var apiRequest = new RestRequest($"product/tags/{HttpUtility.UrlPathEncode(string.Join("+", tags))}");
Daje to ścieżkę równą:
Z drugiej strony NIE twórz dynamicznego zapytania na podstawie danych wprowadzonych przez użytkownika. POWINIENEŚ zawsze używać SqlParameter . Z punktu widzenia bezpieczeństwa niezwykle ważne jest również zwrócenie wartości z odpowiednim kodowaniem, aby zapobiec atakom polegającym na wstrzykiwaniu.
~ Pozdrawiam
źródło
Zakoduj zaszyfrowany ciąg oddzielony:
return HttpServerUtility.UrlTokenEncode(Encoding.UTF8.GetBytes("string"));
Odszyfruj zaszyfrowany ciąg oddzielony:
string x = Encoding.UTF8.GetString(HttpServerUtility.UrlTokenDecode(id));
źródło