Erlaube doppelten URL-codierten Anforderungspfaden, gültig zu sein

8

Ich habe eine ASP.Net WebForms-Standardanwendung, die unter IIS 7.0 mit einer integrierten verwalteten Pipeline ausgeführt wird. Viele der Bilder auf unserer Website haben Leerzeichen in ihren Dateinamen (z. B. './baseball drawing.gif' ). Wenn wir diese Bilder in unsere HTML-Seiten einfügen, codieren wir die Pfade per URL, so dass unsere html-Img-Tags wie diese & lt; img src='./baseball%20drawing.gif' />

aussehen

Nun tritt das Problem auf, wenn bestimmte Suchmaschinen und Webcrawler versuchen, unsere Site zu indizieren. Wenn sie unsere Seiten scrappen, werden sie unsere bereits html-kodierten Pfade html kodieren, indem sie Image-Links wie diese './baseball%2520drawing.gif' erhalten, wobei %25 die URL-Kodierung für '%' ist. Dies verursacht zwei Probleme:

  1. Wenn Nutzer Ergebnisse von diesen Suchmaschinen erhalten, erhalten sie defekte Links.
  2. Wenn Benutzer versuchen, zu diesen fehlerhaften Links zu navigieren, werden Fehler in unserem System ausgelöst.

Wie Sie sehen können, ist dies eine Verlierer-Situation. Benutzer erhalten defekte Links und wir bekommen Rauschen in unseren Fehlerprotokollen.

Ich habe versucht herauszufinden, wie ich dieses Problem ohne Glück beheben kann. Hier ist was ich versucht habe:

  1. Setzen Sie <requestFiltering allowDoubleEscaping='true'> in web.config, um den Fehler "404.11 URL Double Escaped" zu verhindern. Dies behob den ersten Fehler, verursachte aber einen neuen, "ein potentiell gefährlicher Request.Path wurde gefunden".
  2. Die% wurde aus dem <httpRuntime requestPathInvalidChars> entfernt, um den Fehler "potenziell gefährlicher Request.Path" zu verhindern. Dies hat den zweiten Fehler behoben, aber jetzt haben wir einen dritten, "Ressource kann nicht gefunden werden".
  3. Ich habe in meinen Code eine Pause eingefügt, um Request.Path zu sehen. Es sieht so aus, als wäre es richtig mit einem Wert von "Ball Image.gif" anstelle von "Ball% 2520Image.gif". In diesem Fall bin ich mir nicht sicher, warum es nicht funktioniert.

Ich habe das Gefühl, einen super Hack zu haben, bei dem ich alles abschalten muss, ohne wirklich zu verstehen, warum nichts funktioniert. Also ich denke meine Frage ist dreifach

  1. Warum hat der Lösungsversuch 1 das Problem nicht behoben?
  2. Warum hat sich Lösung 2 nicht um das Problem gekümmert?
  3. Warum sieht mein Request.Path in Schritt 3 richtig aus, funktioniert aber immer noch nicht?

Jede Hilfe, die jemand zur Verfügung stellen kann, wäre sehr willkommen.

    
Mark Rucker 06.01.2012, 22:25
quelle

2 Antworten

15

OK, nach vielen Recherchen im Internet und vielen Experimenten denke ich, dass ich endlich verstehe, was vor sich geht. Mein Hauptproblem war ein extremer Bestätigungsfehler. Alles, was ich las, sagte, was ich hören wollte und nicht, was es eigentlich gesagt hatte. Ich werde die wichtigsten Punkte zusammenfassen, die ich verstehen musste, um meine Frage zu beantworten.

  1. Zuerst musste ich verstehen, dass IIS und ASP.Net zwei verschiedene Anwendungen sind. Was IIS auf den Punkt bringt, ist, eine Anforderung zu erhalten, diese Anforderung an eine Anwendung weiterzuleiten, die sie verarbeitet, die Ausgabe von der Verarbeitungsanwendung zu erhalten und dann die Ausgabe von der Anwendung zurück an den Anforderer zu senden. Was ASP.Net tut, empfängt die Anforderung von IIS, verarbeitet sie und gibt die Antwort dann an IIS zurück. Das ist eine große Verallgemeinerung des gesamten Prozesses, aber für meine Zwecke ist es gut genug. 1

  2. Eingehende ASP.Net-Anfragen müssen zwei Gatekeeper passieren. Das RequestFiltering-Modul von IIS7 (konfiguriert in system.webserver / requestFiltering 2 ) und dann der ASP. Net HttpRuntime Anfrage Filter (konfiguriert in system.web / httpRuntime 3 ).

  3. Das IIS RequestFiltering-Modul ist das einzige Modul, das eingehende Anforderungen normalisiert und nur einmal die Normalisierung anwendet. Wieder wiederhole ich es nur ein Mal. Auch wenn <requestFiltering allowDoubleEscaping="true" /> gilt, wird die Normalisierung nur einmal angewendet. Das bedeutet, dass "% 2520" auf "% 20" normalisiert wird. An dieser Stelle, wenn allowDoubleEscaping falsch ist, wird IIS die Anfrage nicht durchlassen, da "% 20" noch normalisiert werden kann. Wenn jedoch allowDoubleEscaping auf True gesetzt ist, wird IIS7 die Anfrage '% 20' an den nächsten Gatekeeper, ASP.Net, übergeben. Dies war die Ursache für den ersten Fehler.

  4. Im Asp.net-Filter werden die requestPathInvalidCharacters überprüft. Nun ist unser '% 20' ungültig, weil '%' standardmäßig ein Teil von requestPathInvalidCharacters ist. Wenn wir das '%' aus dieser Liste entfernen, werden wir es durch den zweiten Gatekeeper schaffen und ASP.Net wird versuchen, unsere Anfrage zu bearbeiten. Dies war die Ursache für den zweiten Fehler.

  5. Jetzt versucht ASP.net unseren virtuellen Pfad in einen physischen auf dem Server zu konvertieren. Leider haben wir immer noch eine '% 20' in unserem Pfad statt der '' wollen wir so ASP.Net ist nicht in der Lage, die Ressource zu finden, die wir wollen und wirft eine "Ressource kann nicht gefunden werden Fehler". Der Grund, warum der Pfad für mich richtig aussah, als ich meinen Code einbrach, liegt darin, dass ich die Eigenschaft "Request.Url" überwacht habe. Diese Eigenschaft versucht, hilfreich zu sein, indem sie ihre eigene Normalisierung in ihrer ToString () -Methode anwendet, wodurch unser% 20 wie das "wir wollen, auch wenn es nicht ist" aussieht. Dies war die Ursache für den endgültigen Fehler.

Um dies zu erreichen, könnten wir unser eigenes benutzerdefiniertes Modul schreiben, das die Anfrage nach den ersten beiden Gatekeepern empfängt und vollständig normalisiert, bevor es an ASP.Net übergeben wird. Wenn Sie dies jedoch tun, können alle Zeichen durchkommen, solange sie URL-codiert sind. Zum Beispiel wollen wir normalerweise kein '& lt; oder ein '& gt;' auf unseren Wegen, da diese verwendet werden können, um Tags in unseren Code einzufügen. Wie die Dinge jetzt funktionieren, ist die & lt; und & gt; wird nicht über den ASP.Net-Filter hinauskommen, da sie Teil der requestPathInvalidCharacters sind. Sie können jedoch als% 253C und% 253E codiert werden, wenn wir die ersten beiden Gatter öffnen und dann die Anforderung in unserem eigenen benutzerdefinierten Modul normalisieren, bevor Sie sie an ASP.Net übergeben.

Zusammenfassend lässt sich die vollständige Normalisierung von% 2520 nicht ohne eine große Sicherheitslücke erreichen. Wenn es möglich wäre, dem RequestFiltering-Modul mitzuteilen, dass es jede Anforderung vollständig normalisiert, bevor es diese Anfrage an die ersten beiden Gatekeeper absetzt, wäre es viel sicherer, aber im Moment ist diese Funktionalität nicht verfügbar.

Wenn ich etwas falsch gemacht habe, lass es mich wissen und ich hoffe, das hilft jemandem.

    
Mark Rucker 13.01.2012, 22:41
quelle
0

Wenn Sie doppeltes Escaping zulassen möchten, können Sie den Anweisungen unter folgen Ссылка

Es funktionierte für mich auf IIS 7.0 mit keiner anderen erforderlichen Konfiguration. Double-Escaping hat keine Auswirkungen auf den Code der Website, auf der ich es implementiert habe; Ich weiß nicht, welche möglichen Sicherheitsimplikationen es für andere Sites geben könnte.

    
Andrew Morton 07.01.2012 22:07
quelle