wake-up-neo.net

doppelte Escape-Sequenz innerhalb einer URL: Das Anforderungsfilterungsmodul ist so konfiguriert, dass es eine Anforderung ablehnt, die eine doppelte Escape-Sequenz enthält

In meiner ASP.NET MVC-Anwendung versuche ich, eine URL wie die folgende zu implementieren:

/ product/tags/für + Familien

Wenn ich versuche, meine Anwendung mit Standardkonfigurationen auszuführen, wird diese Nachricht mit dem 404.11-Antwortcode angezeigt:

HTTP-Fehler 404.11 - Nicht gefunden

Das Anforderungsfilterungsmodul ist so konfiguriert, dass es eine Anforderung ablehnt, die eine doppelte Escape-Sequenz enthält.

Ich kann mit diesem Fehler umgehen, indem ich den folgenden Code in meiner web.config implementiere:

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

Also, jetzt bekomme ich keine 404.11.

Ich frage mich, welche Art von Sicherheitslücken ich mit dieser Implementierung öffne.

Übrigens ist meine Bewerbung unter .Net Framework 4.0 und läuft unter IIS 7.5.

78
tugberk

Die Sicherheitslücken, die Sie möglicherweise öffnen, haben mit Code-Injection zu tun - HTML-Injection, JavaScript-Injection oder SQL-Injection.

Die Standardeinstellungen schützen Sie vor Angriffen, indem sie nicht zulassen, dass gängige Injektionsstrategien funktionieren. Je mehr Standardsicherheit Sie entfernen, desto mehr müssen Sie sich überlegen, was Sie mit den über URLs, GET-Anforderungsabfragen, POST Anforderungsdaten, HTTP-Headern usw. bereitgestellten Eingaben tun.

Wenn Sie beispielsweise dynamische SQL-Abfragen auf der Grundlage des Parameters id Ihrer Aktionsmethode erstellen, gehen Sie wie folgt vor:

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

(... das ist NICHT eine gute Idee), der durch das .NET-Framework eingerichtete Standardschutz könnte einige der gefährlicheren Szenarien stoppen , wie der Benutzer, der diese URL anfordert:

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

Die ganze Idee ist, jeden Teil der URLs und andere Eingaben in Aktionsmethoden als mögliche Bedrohungen zu behandeln. Die Standardsicherheitseinstellung bietet Ihnen einen Teil dieses Schutzes. Jede Standard-Sicherheitseinstellung, die Sie ändern, führt zu etwas mehr potenzieller Bedrohung, die Sie manuell behandeln müssen.

Ich gehe davon aus, dass Sie keine SQL-Abfragen auf diese Weise erstellen. Das hinterhältigere ist jedoch, wenn Sie Benutzereingaben in Ihrer Datenbank speichern und später anzeigen. Der böswillige Benutzer könnte JavaScript oder HTML in Ihrer Datenbank speichern, die nicht verschlüsselt ausgehen, was wiederum andere Benutzer Ihres Systems bedrohen würde.

51
Anders Tornblad

Sicherheitsrisiko

Die Einstellung allowDoubleEscaping gilt nur für path (cs-uri-stem) und lässt sich am besten mit OWASP Double Encoding erklären. Die Technik wird verwendet, um Sicherheitskontrollen durch zweimaliges URL-Codieren der Anforderung zu umgehen. Verwenden Sie Ihre URL als Beispiel:

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

Angenommen, es gibt Sicherheitskontrollen speziell für /product/tags/for+families. Eine Anfrage für /product/tags/for%252Bfamilies Ist eingegangen. Dies ist dieselbe Ressource, die jedoch von den oben genannten Sicherheitskontrollen nicht überprüft wird. Ich habe den allgemeinen Begriff der Sicherheitskontrollen verwendet, weil sie beispielsweise einen authentifizierten Benutzer erfordern, nach SQLi suchen usw.

Warum blockiert IIS?

Das Pluszeichen (+) ist ein reserviertes Zeichen pro RFC2396 :

Viele URIs enthalten Komponenten, die aus bestimmten Sonderzeichen bestehen oder durch diese begrenzt sind. Diese Zeichen werden als "reserviert" bezeichnet, da ihre Verwendung innerhalb der URI-Komponente auf ihren reservierten Zweck beschränkt ist. Wenn die Daten für eine URI-Komponente in Konflikt mit dem reservierten Zweck stehen, müssen die in Konflikt stehenden Daten vor der Bildung der URI maskiert werden.

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

Wade Hilmo hat einen ausgezeichneten Beitrag mit dem Titel Wie IIS blockiert Zeichen in URLs . Es werden viele Informationen und Hintergrundinformationen bereitgestellt. Der Teil speziell für das Pluszeichen lautet wie folgt:

AllowDoubleEscaping/VerifyNormalization scheint also ziemlich einfach zu sein. Warum habe ich gesagt, dass es Verwirrung stiftet? Das Problem tritt auf, wenn in einer URL ein "+" - Zeichen angezeigt wird. Das "+" - Zeichen scheint nicht maskiert zu sein, da es kein "%" enthält. RFC 2396 merkt außerdem an, dass es sich um ein reserviertes Zeichen handelt, das in eine URL aufgenommen werden kann, wenn es in maskierter Form vorliegt (% 2b). Aber wenn allowDoubleEscaping auf den Standardwert false gesetzt ist, wird es auch in maskierter Form blockiert. Der Grund dafür ist historisch: In den Anfängen von HTTP wurde ein "+" - Zeichen als Kurzform für ein Leerzeichen angesehen. Bei einigen Kanonisierungsprogrammen wird eine URL, die ein "+" enthält, in ein Leerzeichen umgewandelt. Aus diesem Grund betrachten wir ein "+" in einer URL als nicht kanonisch. Ich konnte keinen Verweis auf einen RFC finden, der diese "+" - Behandlung aufruft, aber es gibt viele Verweise im Web, die davon als historisches Verhalten sprechen.

Aus eigener Erfahrung weiß ich, dass beim Analysieren von Protokollen Verwirrung stiftet, wenn IIS= Anforderungsbereiche durch ein Pluszeichen ersetzt werden. Ein Pluszeichen im Namen kann Verwirrung stiften.

Lösung

Es gibt drei Möglichkeiten, dies zu beheben, und zwei Möglichkeiten, das Pluszeichen weiterhin zu verwenden.

  1. allowDoubleEscaping=true - Dies ermöglicht ein doppeltes Escape für Ihre gesamte Website/Anwendung. Dies kann je nach Inhalt zumindest unerwünscht sein. Der folgende Befehl setzt allowDoubleEscaping=true.

    appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /allowDoubleEscaping:True
    
  2. alwaysAllowedUrls - Die Anforderungsfilterung bietet einen Whitelist-Ansatz. Wenn Sie diesen URL-Pfad zu alwaysAllowedUrls hinzufügen, wird die Anforderung nicht durch andere Einstellungen für die Anforderungsfilterung überprüft und in der Anforderungspipeline IIS=) fortgesetzt. Hier besteht die Sorge, dass die Anforderungsfilterung die Anforderung nicht überprüft zum:

    • Anforderungsgrenzen: maxContentLength, maxUrl, maxQueryString
    • Verben
    • Abfrage - Abfragezeichenfolgenparameter werden nicht überprüft
    • Doppelte Flucht
    • High-Bit-Zeichen
    • Anforderungsfilterregeln
    • Header-Limits anfordern

    Mit dem folgenden Befehl wird /product/tags/for+families Zu alwaysAllowedUrls auf der Standardwebsite hinzugefügt.

    appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"alwaysAllowedUrls.[url='/product/tags/for+families']"
    
  3. Umbenennen - ja, benennen Sie einfach die Datei/den Ordner/den Controller/usw. wenn möglich. Dies ist die einfachste Lösung.

2
user2320464

Ich habe mich darum gekümmert. Wenn Sie die verschlüsselte Zeichenfolge in die URL für (IIS) einfügen möchten, müssen Sie sie von "dirty" säubern: {";", "/", "?", ":", "@", "&", " = "," + "," $ ",", "}; und wenn Sie es entschlüsseln und erneut verwenden möchten, müssen Sie es vor dem Entschlüsseln erneut verschmutzen (um das gewünschte Ergebnis zu erzielen).

Hier ist mein Code, ich hoffe er hilft jemandem:

 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;
        }
1
mark dibe

Ich bin also darauf gestoßen, als ich eine API von einer MVC-App aus aufrief. Anstatt die Sicherheitslücke zu öffnen, änderte ich meinen Pfad.

Zunächst einmal empfehle ich, diese Einstellung NICHT zu deaktivieren. Es ist zweckmäßiger, das Design der Anwendung/Ressource zu ändern (z. B. den Pfad zu codieren, die Daten in einem Header oder im Body weiterzuleiten).

Obwohl dies ein älterer Beitrag ist, dachte ich, ich würde Ihnen mitteilen, wie Sie diesen Fehler beheben können, wenn Sie dies von einem Aufruf einer API erhalten, indem Sie die HttpUtility.UrlPathEncode -Methode in System.Web) verwenden .

Ich benutze RestSharp um Anrufe zu tätigen, also benutze mein Beispiel die RestRequest:

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

Dies erzeugt einen Pfad gleich:

/ product/tags/für% 2Bfamilien

Erstellen Sie NICHT eine dynamische Abfrage, die auf den Eingaben eines Benutzers basiert. Sie sollten immer ein SqlParameter verwenden. Aus Sicherheitssicht ist es außerdem äußerst wichtig, die Werte mit der entsprechenden Codierung zurückzugeben, um Injektionsangriffe zu verhindern.

~ Prost

0
Rogala