• 5

A PHP Error was encountered

Severity: Notice

Message: Undefined index: userid

Filename: views/question.php

Line Number: 191


File: /home/prodcxja/public_html/questions/application/views/question.php
Line: 191
Function: _error_handler

File: /home/prodcxja/public_html/questions/application/controllers/Questions.php
Line: 433
Function: view

File: /home/prodcxja/public_html/questions/index.php
Line: 315
Function: require_once

name Punditsdkoslkdosdkoskdo

Creating a Secure File Hosting Server for PDFs

I'm working to develop a website that allows clients to log in and see various PDFs saved on the server. These PDFs will be unique to the client and should not be accessible by someone who is not logged in. Getting the files onto the server shouldn't be an issue, I'm just not sure on how to serve them to end users.

I've implemented this kind of thing with data from SQL servers being served instead of files, so I'm not entirely sure what the most effective way to go about this.

The website is on a LAMP and my minimal experience is in PHP (but if a framework or other language would make this easier, I can learn it).

I'm probably in over my head but I usually am, so any input would be great.

Put the files outside of the webroot. Then using PHP pass the file though a script. That way no one can link to the file directly and bypass your controls. (Naturally make sure the script that does this only after verifying the user has permission to retrieve that file).

Sample PHP:

    if (!isset($_SESSION['authenticated'])) {
    $file = '/path/to/file/outside/www/secret.pdf';

    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename=' . basename($file));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
  • 9
Reply Report
      • 1
    • Actually, yes, it should be. I was so focused on the core concept I did not provide a truly complete example. Gonna fix that now...

The easy way is to give these files long random filenames (say, 20 random characters). Technically they will be accessible by anyone, but it will not be possible to guess the URL, so only authorized people will have access.

Alternatively John Conde already outlined a way to serve a file from a PHP script. It will incur a small performance penalty, but will be as secure as your code is. The only thing I can add is that if you cannot place them outside webroot, then you might be able to use .htaccess to prevent people from accessing the files directly.

  • 4
Reply Report
    • I would suggest GUID. This still has the problem that I can ping the server until I get something interesting, although you can make the chances of success vanishingly small. I do support the use of .htaccess to block access to the folder.
      • 2
    • @zebediah49 - It's a possibility, but there are pitfalls that you should be aware of. Simply generating a random string is safer. And, if you want to be 110% certain, use a cryptographically strong random number generator.
      • 1
    • Very interesting, thanks. I picked GUID for length, but I would still avoid using publicly accessible URLs, but that's a very good point.
      • 1
    • GUID has 32 characters, but only 16 possibilities for each character. 20 random characters from a-z9-9 have 36 possibilities for each position.

John posted the primary correct way of doing it, so I'm adding the (probably inferior) alternative: Serve it from the database. Just have a BLOB column for the PDF, and read/store the file data from the database. You'll end up with a quite large table, but it will work. Serving it requires setting the same header()s as John posted, you just send off the data from the DB instead of from the file.

This has the advantage of not having to ensure you don't have filename collisions, etc.

  • 2
Reply Report

Warm tip !!!

This article is reproduced from Stack Exchange / Stack Overflow, please click

Trending Tags

Related Questions