Why is it a security risk to allow encoded slashes in a URI?
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开发者_JAVA技巧 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.
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.
Honestly, I don't see any security issues with this, but I must admit I've not worked in this field much. That said, the rule is still not correct.
You should be redirecting to a handler file (php script) which parses $_SERVER['REQUEST_URI']
instead of passing it through $_GET
. This is mostly to avoid issues you'd normally get with non-encoded content.
On the other hand, you may be running a web app firewall with a rule against passing slashes through URI. This is because this behavior is often associated with Remote Code Execution, Local File Access and Directory Traversal. This, however, is a precautionary measure, one which you really shouldn't rely on in the first place.
An example PoC exploit:
include 'languages/'.$_GET['lang']; // hacker may pass ../ to move around.
精彩评论