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.
0 Kommentare