Restrict file access — only read through PHP [closed]

丶灬走出姿态 提交于 2019-11-28 09:17:03

Since you can't put the files anywhere but in your public_html directory, you'll have to go for the feared/hated "security by obscurity" method

  1. Create a randomly named sub-directory to store the files in: public_html/RANDOMGARBAGE

  2. Make sure the directory is not browseable. Disable directory browsing (if you can), and put a default document (index.html?) in there as well, so even if browsing is on, you won't get the directory listing.

  3. Don't store your files with guessable names. Instead of storing them with the database ID, store them with a salted+hashed name instead: $crypted_filename = sha1($real_filename . 'some hard-to-guess salt text'); (of course, make this more complex if you need to). Store the original filename in your database. So you end up with something like:

    public_html/RANDOMGARBAGE/5bf1fd927dfb8679496a2e6cf00cbe50c1c87145 public_html/RANDOMGARBAGE/7ec1f0eb9119d48eb6a3176ca47380c6496304c8

  4. Serve up the files via a PHP script - never link to the hashed filename directly

    Download

which then does:

<?php

    $fileID = (int)$_GET['fileID'];

    $crypted_file = sha1($fileID . 'some hard-to-guess salt text');

    $full_path = 'public_html/RANDOMGARBAGE/' . $crypted_file;
    if (is_readable($full_path)) {
         if(user_is_allowed_to_see_this_file()) {
             /// send file to user with readfile()
             header("Content-disposition: attachment; filename=$ORIGINAL_FILENAME");
             readfile($full_path);
         } else {
             die("Permission denied");
         }
    } else {
        /// handle problems here
        die("Uh-oh. Can't find/read file");
    }

This way the user will never see what your "s00per seekrit" filename is, they'll just see their browser hit ...php?fileID=37 and start a download of secret file.pdf

On top of this, you can occasionally rename the special sub-directory to something else on a regular basis, as well as change the salt text (which then requires you update all the hashed filenames with the new sha1 values).

You can simply hide them. It's security-through-obscurity, but it sounds like your best option if you can't either keep them out of the web-root, or find a way to tell the server not to serve them directly.

So stick them in some randomly-named directory:

asd8b8asd8327bh/123.pdf
asd8b8asd8327bh/124.pdf
asd8b8asd8327bh/125.pdf
...

Then write yourself a little PHP script that will send appropriate headers, and pass the file contents through.

for example:

<?PHP
//pdf.php
$id = $_GET['id'];

//make sure nobody is doing anything sneaky. is_numeric() might do the trick if the IDs are always integers.
if (!some_validation_passes($id)){
  die();
}
<?php

header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="'.$id.'.pdf"');
readfile('asd8b8asd8327bh'.$id.'pdf');

Now, the above is really no better than just serving the files directly (yet), since people can still increment the id parameter in the query string.

But you ought to be able to figure out how to handle authorization pretty easily.

Because PHP uses the web server user's permissions, there is no way to restrict access to the files without either:

  • Placing them outside the DOCROOT
  • Changing the web server configuration to disallow access to those files
  • Changing the file so it will be interpreted by the web server, thus hiding its contents

Putting them in a database counts as outside the DOCROOT. For the third option, you could make the PDFs PHP files, but honestly, that would be pretty convoluted.

I recommend you contact GoDaddy and see if they have some way to configure per-directory file permissions.

Robert

Make a folder web inaccessable via chmod. PHP will still be able to include/require whatever is on the server, but users will not be able to navigate to the files ever.

Example: This is set to 770, IE User and Group can Read/Write/Execute, Other can do nothing.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!