0

In my php file I use a $_GET parameter to open a file on my server, like so:

$filename = $_GET["filename"];
$content = file_get_contents("/path_to_files/".$filename);

My question is, how do I make this more secure so the user cannot access files in parent folders on the server? Is this something I need to do on the server such as permissions and/or configurations? Or should $filename be validated in my php file? Thanks in advance!

Neil Harlow
  • 110
  • 2
  • 11

5 Answers5

5

The most secure way is to avoid external parameter in using file paths.. You can implement something like this:

$files = array (
    'file1' => 'path/to/file1.php',
    'file2' => 'path/to/file2.php',
    'file3' => 'path/to/file3.php',
    ...
);

if ( in_array($_GET['file'], array_keys($files) ) )
{

    $content = file_get_contents($files[$GET['file']]);
}

Else... check the approaches from here: string sanitizer for filename

Community
  • 1
  • 1
lu cip
  • 715
  • 5
  • 8
1

I don't think you have to do something about permissions on your server as it's php which access the file actually, not the user.

You may check $filename against a white list of files. Can you provide more info about what you're trying to do?

syl.fabre
  • 696
  • 1
  • 7
  • 20
  • Thanks for the feedback. Basically Im just reading a given html file and outputting it as html. Since I have a pre-determined list of files that can be outputted I think the whitelist approach will work perfect. – Neil Harlow Sep 18 '13 at 06:56
1

Best is to have "whitelist" for allowed files;

U could have something like filename patters, [someName] [dot] [extension]

if (!preg_match('/^[a-zA-Z0-9_-]+\.[a-zA-Z0-9]+$/', $filename) {
   throw new Exception('file not allowed');
}

but this way, user could access all files in /path_to_files/ directory

po_taka
  • 1,816
  • 17
  • 27
1

The method you have posted is not a very secure way and you should think about changing it.

If you need to use this method then please make the following changes to your script

$filename = basename($_GET["filename"]);
$content = file_get_contents("/path_to_files/".$filename, false);

The false parameter in the file_get_contents function will only look for the file in the path you have provided and no where else.

asarfraz
  • 518
  • 3
  • 8
  • I was looking for something like this but did not see it on php.net. Is there any way you can provide me with a link explaining the false parameter? thanks! – Neil Harlow Sep 18 '13 at 07:02
0

White list seems to be the best secure way but you may use a script like this

$file = realpath("/path_to_files/" . $_GET['filename']);
// Check that $file is actually in the specified path
if(substr($file, 0, strlen("/path_to_files/")) == "/path_to_files/"){
    include($file);
}

But I don't know if it's possible to fool realpath ...

syl.fabre
  • 696
  • 1
  • 7
  • 20