IIS behandelt doppelt codierte Schrägstriche in URLs bei der ersten Anforderung anders als bei nachfolgenden Anforderungen

8

Kürzlich wurde mein Team gebeten, ein HttpModule für eine ASP.NET MVC-Anwendung zu implementieren, die doppelt codierte URLs auf IIS 7 und .NET 3.5 behandelte. Hier ist der Kern des Problems:

Manchmal erhalten wir URLs mit doppelt codierten Schrägstrichen, die wie folgt aussehen:

%Vor%

Es gibt noch andere Formate, die wir behandeln müssen, aber alle haben etwas gemeinsam, sie haben einen doppelt kodierten Schrägstrich.

Um das zu beheben, haben wir ein HttpModule geschrieben, das nur funktioniert, wenn eine URL einen doppelt kodierten Forward-Schrägstrich hat, und wir leiten es an eine vernünftige URL weiter. Die Details sind nicht wichtig, aber es gibt zwei Bits, die sind:

  1. Wir können nicht kontrollieren, dass diese URLs doppelt codierte Schrägstriche enthalten
  2. Und wir haben uns weder auf .NET 4.0 noch auf den unmittelbaren Horizont bezogen.

Hier ist das Problem:

Die erste Anfrage nach dem Start von IIS zeigt eine andere URL als die zweite Anfrage.

Wenn wir die URL aus dem obigen Beispiel verwendet hätten, würde die erste Anfrage an IIS wie folgt aussehen:

http://www.example.com/bar/baz/foo

und die zweite Anfrage würde wie folgt aussehen:

http://www.example.com/%252fbar%5cbaz/foo

Dies wurde getan, indem die Eigenschaft Application.Request.Url.AbsolutePath beim Debugging untersucht wurde.

Hier ist das kleinste Codebeispiel, das das Problem reproduzieren sollte (erstellen Sie eine neue MVC-Anwendung und registrieren Sie das folgende HttpModule):

%Vor%

Rufen Sie dann dieselbe URL auf localhost auf:

%Vor%
  

Hinweis: Stellen Sie sicher, dass Sie vor der Zeile in Debugger.Launch() einen context_BeginRequest -Aufruf einfügen, damit Sie ihn beim ersten Start von IIS

sehen können

Wenn Sie die erste Anfrage ausführen, sollten Sie folgendes sehen:

http://example.com/bar/foo

Bei nachfolgenden Anfragen sollten Sie sehen:

http://example.com//bar/foo .

Meine Frage ist: Ist das ein Fehler in IIS? Warum bietet es verschiedene URLs beim ersten Aufruf von Application.Request.Url.AbsolutePath , aber nicht für eine nachfolgende Anfrage?

Auch: Es spielt keine Rolle, ob die erste Anfrage eine doppelt codierte URL ist oder nicht, die zweite Anfrage wird immer von IIS entsprechend gehandhabt (oder zumindest so gut wie die Handhabung doppelt codierter Forward Slashes sein kann) . Es ist diese erste Anfrage, die das Problem ist.

Aktualisieren

Ich habe ein paar verschiedene Eigenschaften ausprobiert, um zu sehen, ob man bei der ersten Anfrage andere Werte hat:

Erste Anfrage %Vor%

Die einzige interessante Sache ist, dass Application.Request.RawUrl einen single-codierten Forward-Schrägstrich ( %2f ) ausgibt und den kodierten umgekehrten Schrägstrich ( %5c ) in einen forwardslash umsetzt (obwohl alles andere auch das tut).

Das RawUrl ist bei der ersten Anfrage noch teilweise verschlüsselt.

Zweite Anfrage %Vor%

Interessante Punkte aus der zweiten Anfrage:

  • IsWellFormedOriginalString() ist false . Auf die erste Anfrage war true .
  • Die RawUrl ist dieselbe (möglicherweise hilfreich).
  • Die AbsoluteUri ist anders. Auf der zweiten Anfrage hat es zwei Schrägstriche.

Aktualisieren

%Vor%

Offene Fragen

  • Dies scheint ein Fehler in IIS oder .NET zu sein. Ist es?
  • Dies ist nur wichtig für die allererste Anfrage, die von einer Anwendung nach einem iisreset gemacht wird.
  • Abgesehen von der Verwendung von RawUrl (da wir uns um viele andere Probleme kümmern müssen, wenn wir die Raw-Url analysieren, statt die von .NET bereitgestellte "sichere" URL zu verwenden), gibt es andere Methoden, wie wir damit umgehen können ?

Beachten Sie, dass die physikalischen Auswirkungen dieses Problems gering sind: Damit es sich um ein tatsächliches Problem handelt, müsste die erste Anfrage an den Webserver von einem Client für die oben angegebene URL und die damit verbundenen Chancen erfolgen sind relativ niedrig.

    
George Stocker 31.08.2011, 00:22
quelle

2 Antworten

2

Request.Url kann bereits dekodiert werden - ich würde es nicht für das, was Sie tun, vertrauen.

Siehe die internen Details unter: Querystring mit url-codierten Ampersand vorzeitig in Request.Url decodiert

Die Lösung besteht darin, direkt über Request.RawUrl auf die Werte zuzugreifen.

Ich erkenne, dass dein Problem mit dem Pfad ist, aber es scheint, dass das Gleiche passiert. Probieren Sie die RawUrl - sehen Sie, ob es stattdessen für Sie arbeitet.

    
Adam Tuliper - MSFT 31.08.2011 04:00
quelle
0

Das ist wirklich keine Antwort, aber möglicherweise ein Schritt in die richtige Richtung. Ich hatte keine Zeit, ein Testkabel zu erstellen, um irgendetwas zu beweisen.

Ich habe this.PrivateAbsolutePath über Reflector verfolgt und es geht weiter und weiter. Es gibt eine Menge von String-Manipulation, wenn auf sie zugegriffen wird.

%Vor%     
rick schott 31.08.2011 02:09
quelle

Tags und Links