Apache mod_rewrite double encodes query string on redirect

6,484

This seems to be a bug in Apache. This bug report is a bit messy, but describes your problem exactly:

https://issues.apache.org/bugzilla/show_bug.cgi?id=34602

It looks like they are aware of the issue. Though the bug claims they have fixed, I have tested this with Apache 2.3.15, and the problem still seems to be there. Also note that Apache 2.3 is a beta version, so it's no use to you even if it did fix it, until Apache 2.4 is out.

Share:
6,484

Related videos on Youtube

Erik Hesselink
Author by

Erik Hesselink

Updated on September 18, 2022

Comments

  • Erik Hesselink
    Erik Hesselink almost 2 years

    We've encountered a strange issue (a bug, perhaps?) with Apache mod_rewrite's behavior when passing through query strings.

    To reproduce, we've set up a clean Ubuntu (oneiric) install with the default Apache configuration. We have enabled mod_rewrite, and in the default site configuration, we've added the following:

    RewriteEngine on
    RewriteRule ^/(.*)$ /r/$1 [R]
    

    To test, we use curl:

    curl -I 'http://[ubuntu-machine]/a/b%20c?a%20b'
    

    The relevant output is:

    HTTP/1.1 302 Found
    Server: Apache/2.2.20 (Ubuntu)
    Location: http://[ubuntu-machine]/r/a/b%20c?a%2520b
    

    As you can see, the query string is double-escaped, which is wrong. Does anyone have any idea how we could fix this? A couple of things we've tried:

    • Adding [NE]. This gives us the correct query string, but the path is unescaped, which leads to new problems.
    • Adding [NE,B]. This seems to work, but causes the / between the a and b parts of the path to be escaped.
    • Unescaping the query string manually.

      RewriteCond %{QUERY_STRING} .*
      RewriteMap unescape int:unescape  
      RewriteRule ^(.*)$          $1?${unescape:%{QUERY_STRING}}
      

      However, this means we cannot distinguish between, say, an & and an escaped & in the query-string.

    Update:

    This bug report describes the same issue. The first comment links to a commit apparently fixing the issue, but as Pieter says below, it doesn't seem like it is actually fixed.

  • Arjan
    Arjan over 9 years
    Seems that Apache 2.4.10 is still doing this, though it should have been fixed in 2.4.1.
  • François
    François almost 8 years
    I still see the issue in 2.4.7