My friend found a problem in my script, it gives acces to root files.
This url gives passwd file:
http://site.com/attachment.php?file=../../../../../../etc/passwd
How to escape this security hole?
My friend found a problem in my script, it gives acces to root files.
This url gives passwd file:
http://site.com/attachment.php?file=../../../../../../etc/passwd
How to escape this security hole?
Dont download the files using URL String.... Define unique IDs to denote a file, rather than paths.
You might have seen downloads like this http://www.mysite.com/download.php?id=23423
what they do, use this id, to take out the file name and path from the db and then download it.
I suppose you have a directory where all attachments are stored.
Just test if file is located in your directory.
// http://www.php.net/manual/en/function.basename.php
// http://cz.php.net/manual/en/function.file-exists.php
if (file_exists($attachments_path . "/" . basename($_GET['file'])) {
// do work
}
Starx posted a solution which seems fine. It can be done without a database, though. If somebody uploads a file you can store the file as md5($filename).$extension
and use your script.
You can use realpath()
and dirname()
to check URLs against $_SERVER['DOCUMENT_ROOT']
(or whatever directory is "safe" for downloading).
If the result of realpath()
points outside the safe directory, you can deny the download request.
There's also the open_basedir security directive (and runtime option as of 5.3).
There are several different solutions. If there can be only a filename, a basename() solution would work.
However, if it can be path, a more complex solution is needed
//assume current directory, but can be set anything. Absolute path of course
$basedir = dirname(__FILE__);
//assume our files are below document root.
//Otherwise use it's root dir instead of DOCUMENT_ROOT
$filename = realpath($_SERVER['DOCUMENT_ROOT'].$_GET['file']);
if (substr($systemdir,0,strlen($basedir)) !== $basedir) {
header ("HTTP/1.0 403 Forbidden");
exit;
}
there is also a useful PHP configuration option open_basedir