php

Stolperfalle mit mod_rewrite und Rückreferenzierung

Vor ein paar Tagen habe ich einen Blog-Beitrag gelesen, in dem es eigentlich um base62-Kodierung ging. Die Motivation für die unübliche Kodierung war aber ein unerwartetes Verhalten von mod_rewrite, dass mir so bisher auch nicht aufgefallen war:

There’s a really horrible bug (though they won’t call it that!) in Apache’s mod_rewrite that means that urlencoded inputs in rewrites get unescaped in their transformation to output patterns. The bug actually remains unfixed, though a workaround first appeared in Apache 2.2.12 (which wasn’t all that long ago). Put it like this: if you’re not using the [B] flag in your mod_rewrite rules, your site is probably only working due to blind luck.

RewriteRules, die Rückreferenzierungen verwenden und das B-Flag nicht gesetzt haben, entfernen auch gleich die URL-Maskierung. Oder wie es im Apache-Manual steht:

[…] will map /C++ to /index.php?show=/C++. But it will also map /C%2b%2b to /index.php?show=/C++, because the %2b has been unescaped. With the B flag, it will instead map to /index.php?show=/C%2b%2b.

Diese Verhalten kann einem im Zusammenhang mit verschlüsselten oder kodierten Werten in der URL ganz schön in die Suppe spucken. Mir fällt gerade auch kein Fall ein, wo ich dieses Verhalten als sinnvoll oder nützlich empfinden würde. Daher werde ich in Zukunft alle RewriteRules mit Rückreferenzierungen prophylaktisch mit dem B-Flag ausstatten.

Update (18.08.2011):

Ok, es gibt doch einen sinnvollen Anwendungsfall, weil das B-Flag sich nicht darum kümmert, ob die Eingabe kodiert war oder nicht. Im Apache-Manual wird folgende Regel als Beispiel genommen:

RewriteRule ^(/.*)$ /index.php?show=$1

In diesem Beispiel funktioniert alles und das B-Flag ist super, weil die Rückreferenzierung in den Query-String kommt und daher auf jeden Fall escaped werden muss. Wenn mann aber auf einen Pfad rewriten will, wie mit dieser Regel

RewriteRule ^(.*)$ /de/$1

kommmt einem das B-Flag in die Quere, weil es aus index.php ein /de/index%252ephp macht. Solange man entweder in den Query-String oder auf den Pfad rewriten will, ist alles kein Problem: Bei Query-String das B-Flag verwenden, ansonsten nicht. Aber wenn man sowohl in den Query-String als auch den Pfad mit Rückreferenzierungen verändern will wird das Ganze kompliziert.

Hinterlasse einen Kommentar

1 Kommentar auf "Stolperfalle mit mod_rewrite und Rückreferenzierung"

Benachrichtige mich zu:
avatar

Sortiert nach:   neuste | älteste | beste Bewertung
Marcus Bointon
Gast
6 Jahre 1 Monat her

Thanks for the translation. The apache manual isn’t very clear, so I’ve created a bug report for the B-flag docs: https://issues.apache.org/bugzilla/show_bug.cgi?id=51669.
When using the B flag, you’re very likely to need to set the AllowEncodedSlashes directive as well otherwise you’ll get mysterious 404s if you submit terms that contain a /.

wpDiscuz
Weitere Beiträge zum Thema
Unser neuester Magento-Shop ist online: Sanetta
Kurzer Überblick über das User Centered Design
Mit uns zur „Zukunft des E-Commerce“: Flagbit bei der Internet World in München
Einzelne EAV-Attribute performant speichern