-1

I have a slight problem, I am trying to create a simple security check in my PHP application.

Let's assume for the argument's sake that I have the following folder structure:

website home (httpdocs)
|_file_1
|_file_2
|
|_DIR_1
| |_file_3
| |_file_4
|
|_DIR_2
| |_something.php
| |_file_5
|
|_public
  |_index.php

In this example let's say that the user can visit the /DIR_2/something.php (though the request will be routed through /public/index.php), and can also provide an argument in the url such as ?get_file=file_5. Normally only DIR_2 is publicly accessible and the router which is inside public/index.php would handle the file reading and return the output with correct headers.

Now let's say that the user has provided the following url /DIR_2/something.php?get_file=../DIR_1/file_3. the code will execute it without any problems but that a security risk since only DIR_2 should be accessible.

So, my question is: Is there a PHP function I could use to check if the path to a file (or dir) leads outside a specific directory, so something like

$filePath = $_GET['get_file'];
if(file_outside(__DIR__, $filePath)){
    echo "file is outside the dir";
} else {
    echo "file is inside the dir";
}

I've tried searching but unfortunately all results are about checking whether the path is to a file or a dir or whether the file exists or not, which is not what I need.

I am using php 8.0 in case it's important.

GWS
  • 1
  • This is called a [path traversal attack](https://owasp.org/www-community/attacks/Path_Traversal) and is very common. Most secure is probably safe-listing known valid URLs, and rejecting everything else. Another option is building the full absolute file path and comparing it against known sand paths. See the OWASP for a starter – Chris Haas Oct 27 '22 at 03:03
  • Many thanks @ChrisHaas, I will start there and for now leave this question open. Unfortunately, I am unable to create a safelist as the URLs get matched against regex in the router class in my case, and the pages don't actually exist as files, they get pulled from the DB. I simplified my issue since I didn't want to add any ambiguity to the question. – GWS Oct 27 '22 at 04:21

1 Answers1

0

as described in the: https://stackoverflow.com/a/4205278/12250388

one should use realpath() a function available in php to get the real path of the file and then compare it to the path(s) to a directory where you expect the file to exist in.

Many thanks to @ChrisHass for nudging me in the right direction.

GWS
  • 1