I set up Apache with mod_wsgi
in a default installation, with a very simple test application test.wsgi
that goes like this:
def application(environ, start_response):
status = '200 OK'
output = 'Path: %s' % environ['PATH_INFO']
response_headers = [('Content-type', 'text/plain'),
('Content-Length', str(len(output)))]
start_response(status, response_headers)
return [output]
Apache itself is basically configured like that:
WSGIScriptAlias / /home/user/wsgi_test/test.wsgi
Now if I access URLs on that server, I get the following output:
GET /test/../test/./test
=>Path: /test/test
GET /test/%2E%2E/abc
=>Path: /abc
GET /test%2fabc
=>404 Not found
(due toAllowEncodedSlashes off
, I suppose)
Thus it looks to me that Apache resolves/pre-processes these URLs before passing them to the application, which is nice because it can prevent a lot of local file inclusion and directory traversal attacks where the file path is not part of the query string.
Can one rely on this behaviour or is there some nasty way to trick Apache into actually passing a URL like /test/foo/../bar
to the application? Would it be an Apache bug if that was possible?
The security guideline "Defense in Depth" suggests that you should configure Apache to preprocess paths, but you should also protect against dangerous paths yourself.
Since you probably know a lot more about what the valid paths should look like, you should be able to come up with a lot more restrictive test that's also easier to get right than anything Apache can do in general.