0

I need to code a file browser and want to implement it in a dynamic manner. (so theoretically every folder can be browsed)

To prevent access outside the root folder I thought of the following concept:

  • Client never ever gets to see the absolute paths.
  • The client always requests relative paths.
  • Server appends root folder to relative path and converts the path with realpath.
  • Server checks if the resulting path begins with the specified root directory.

Example:

Root folder is /var/www (always put through realpath first).

  • Client requests /../
  • Server appends root folder -> /var/www//../ and calls realpath -> /var/.
  • Server checks if /var/ starts with /var/www -> false -> hence permission denied.

Here the implementation I thought of (crudely coded):

$rootFolder = realpath('/var/www/');

function to_absolute_path($relativePath) {
    global $rootFolder; // <- i know, globals are evil >:)

    $absolutePath = $rootFolder.'/'.$relativePath;

    return realpath($absolutePath);
}

function verify_permission($absolutePath) {
    global $rootFolder;

    if (!$absolutePath) return false;

    // strlen($rootFolder) is also cacheable, i'm aware
    return substr($absolutePath, 0, strlen($rootFolder)) === $rootFolder;
}

$absolutePath = to_absolute_path($clientRequestedFile);

if (!verify_permission($absolutePath)) {
   // Permission denied
}

It seems to work fine but I really want to get this right to prevent nasty bugs.

Can someone confirm my logic?

BTW:

In the case of symlinks, I thought I would just follow the symlink and apply verify_permission when I arrived at the destination.

marco-a
  • 4,996
  • 1
  • 15
  • 41
  • 1
    Since your code seems to work, and you just want to confirm best practice etc, you should post it in [Code Review](http://codereview.stackexchange.com/) instead. However, I think it looks solid. – Magnus Eriksson Dec 23 '16 at 13:10
  • Ok according to the answer(s) it seems that this is the best way to do it. – marco-a Dec 23 '16 at 13:17

0 Answers0