Graham Dumpleton
grahamd at dscpl.com.au
Fri Aug 4 22:51:01 EDT 2006
On 05/08/2006, at 2:42 AM, Jim Gallacher wrote: > Thomas J. Schirripa wrote: >> def handler(req): >> fields = util.FieldStorage(req) >> #Note: the filename is an absolute path, so I am going to >> split that up into directory and filename for clarity >> filename = os.path.basename(fields["filename"]) >> path = os.path.dirname(fields["filename"]) >> req.headers_out["Content-Disposition"] = "attachment; filename=% >> s" % filename >> req.content_type = "text/plain" >> req.sendfile("%s/%s" % (directory, filename)) >> return apache.OK > > Also, it goes without saying that the filename provided > by in the request should not be trusted. Do some checking to ensure it > is valid value. What Jim has pointed out can't be overemphasised enough. The way your script is written I could potentially steal you /etc/passwd file and much more. What you should at least do is something like the following: ALLOWED_PREFIX = '/some/path/to/fetchable/files' def handler(req): ... fullpath = os.path.normpath(fields['filename']) if not fullpath.startswith(ALLOWED_PREFIX): return apache.HTTP_BAD_REQUEST The os.path.normpath() eliminates any '.' and '..' directory references. You then check to ensure the path then actually begins with the path prefix for where your files actually live. Better still, do not use an absolute path, instead only ever send back a relative path. You should still use os.path.normpath() to eliminate '.' and '..' references. Then, you add the relative path to a path prefix which is only defined within your script. In other words, you never send the path prefix back to the client. Graham
|