Laravel: How to prevent users loading files from outside the base path

Viewed 122

I have a Laravel website and I have several routes that load the contents of images from Storage. I do this using the following code:

public function show_image($name) {
    echo Storage::disk('images')->get($name);
}

I want to prevent users being able to set name to something like ../../../error.log. So I don't want users to escape the Storage directory. I have a few ideas on how to accomplish this however I want to know is there a best practice?

2 Answers

If you need just file name, not location, disallow them from inputting folder of any kind. Just cut the string on /.

end(preg_split("#/#", $name)); 

When you need to allow some folders and all of the contents, check the folder name, subfolder name, etc.

You could either keep a registry/index of the uploaded images, and only allow the user to show a image from that registry (e.g. an images database table).

Or you could do a scan of the directory, that you are allowing files from, and make sure, that the requested file is in that list.

public function show_image($name) {
    $files = Storage::disk('images')->files();
    if (! in_array($name, $files)) {
        throw new \Exception('Requested file not found');
    }

    echo Storage::disk('images')->get($name);
}

(code untested)

Related