You should not use HTTP request parameters as filenames

August 23, 2009

One corollary of the danger of over-powerful introspection is that you should not use HTTP request parameters directly as filenames for any reason, not just to avoid hard-coding allowed commands in your web application. Any time that you use a request parameter as a filename, you create an opportunity for an attacker to escape from whatever directory your application is supposed to get its files from and thus to rummage all over your system.

(In fact, you should not directly use the URL for a filename either, because someday an attacker may feed you a HTTP request for a URL with embedded /../ components. In theory your general web server environment should reject or fix up such URLs without passing them to your application. In practice, this may not happen in some server environments, so it's unwise to count on it in general.)

It pretty much doesn't matter exactly what you're doing with the file; an attacker can probably find some way of exploiting whatever you're doing. (If nothing else, there are usually files that cause undesirable side effects when opened or read from, including blocking your application. Are you prepared to deal with an endless stream of random data, for example?)

The reasonably cautious way to deal with this is to carefully validate the request parameter to reject bad things like /../. Part of the difficulty is always doing this (you may want to put it in some low-level 'open a file' routine), and part of the difficulty is making sure that you get all of the special cases on all of the platforms that you support (or that your code will get used on).

The really cautious approach is to work the other way. Instead of ultimately validating the request parameter by trying to open a filename based on it, get a directory listing of the directory where all the files are and check that the request parameter matches one of the entries. Although it's more work, this automatically defeats pretty much any weirdness that an attacker can attempt.


Comments on this page:

From 195.26.247.140 at 2009-08-24 11:29:13:

Should the title of this blog post be "Don't use any user-supplied data without first filtering?" rather than http request parameters? :)

The super-cautious method (ensure that the parameter is valid, rather than attempting to filter out the bad) should be the method which is always chosen. This is the same reasoning as firewalls blocking everything by default and only allowing specified traffic/ports through.

Written on 23 August 2009.
« A gotcha with Python's new signal.siginterrupt()
Anti-spam content scanning systems need to scan more »

Page tools: View Source, View Normal, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Sun Aug 23 00:26:42 2009
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.