Hi
We have some php code using the file_get_contents() function, and I understand this is vulnerable to direcoty traversel attacks. Given the following code:
$mydata=$_GET['thefile'];
$data = file_get_contents ('/var/html'.$file);
echo $data
How can I do some simple input filtering so I can block the posibility that someone might do directory traversel by playing around with my input?
/MR
You want basename:
$mydata = basename(realpath($_GET['thefile']));
Appended to (slight modifications of) your example:
$file=$_GET['thefile'];
$mypath='/var/www/';
$location= basename(realpath($mypath.$file));
$data = file_get_contents($location);
echo $data;
Note... although this does some level of error checking, it does no error handling. I'll leave that up to you.
If the $_GET['thefile']
won't use folders like "images/fileX.jpg" you can use basename()
$filename = basename($_GET['thefile']);
readfile('/var/html/'.$filename);
When '../../passwords.txt' is given as $_GET['thefile']
it will be converted by basename
to 'passwords.txt'.
Adding realpath()
inside a basename doesn't add any security.
If your script does need to support subdirectories then use realpath() to determine if it's inside the '/var/html' directory.
$baseDir = realpath('/var/html/'); // (mayby /var/html is a symlink)
$baseDirLength = strlen($baseDir);
$filepath = realpath('/var/html/'.$_GET['thefile']);
if (substr($filepath, 0, $baseDirLength) == $baseDir) {
// Even when all the '../' in the thefile are resolved
// the path is within the $baseDir
} else {
// invalid $_GET['thefile']
}