I have a situation where I want encoded slashes in a URI (%2F
), but my .htaccess
rules are ignored when I make the request, sending me instead to a 404 page. I quickly found the Apache directive AllowEncodedSlashes
, which I plan to turn on, but I still don't understand why it's a security risk in the first place. Couldn't anyone manually transform the encoded slashes to real slashes, if they were trying to be nefarious? (Although I can't see what harm they could do...)
The application I'm testing is written in PHP, and the mod_rewrite rule that interfaces with it looks like:
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^test/(.*)$ /test.php?_escaped_fragment_=$1 [NE,QSA,L]
I just want to make sure I understand the risks before proceeding.
To clarify: Apache does not allow encoded slashes in the path, but they are allowed in the query string. The query string is just as susceptible to the exploits listed by Christian below ("Remote Code Execution, Local File Access and Directory Traversal").
So why did the ASF go so far as to create a special directive just to allow this behavior? I'm not trying to be difficult, I just really don't understand. I think it goes without saying that any user input (including the URI) needs to be verified before using it in any database or file system function.
For example, forward slash characters are used to separate different parts of a URL (or more generally, a URI). Unreserved characters have no such special meanings. Using percent-encoding, reserved characters are represented using special character sequences.
The addition of a slash at the end of a URL instructs the web server to search for a directory. This speeds the web page loading because the server will retrieve the content of the web page without wasting time searching for the file.
I would think it is fine to use escaped slashes anywhere in a URL if escaping is warranted. For instance, the example cited in the following (relevant) question is a very reasonable one:
Is a slash ("/") equivalent to an encoded slash ("%2F") in the path portion of an HTTP URL
As for why it would be disabled by default...this blog entry from back in 2003 suggests it is to "protect lame CGI scripts from themselves":
http://ken.coar.org/burrow/Apache_2f_encoding_decoding_and_security
Certain careless practices probably lead some people to find themselves in a codebase with a string they're unsure whether to unescape or not. So they unescape it "just to be safe". But this may occur after a point that assumed there were no path characters... and it gets passed on into some executable context that believed it had done all the checking it needed to.
So if you're using the recommended methods of most modern web frameworks, I doubt this is a significant issue and you can use AllowEncodedSlashes without much concern.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With