2

I would like to create a very simple php protector on an arbitrary binary file, where the user enters a password and the file is downloaded to their computer, but they must enter the password each time they want to download.

In the first answer to the question Easy way to password-protect php page, the line include("secure.html"); seems to require that the file has to be displayable ascii, renderable by the browser.

Is there a way to protect a binary file, say foo.bin with the same level of simplicity (and similar limited degree of security)?

Community
  • 1
  • 1
merlin2011
  • 71,677
  • 44
  • 195
  • 329
  • I recommend using PHPass for password hashing in PHP, It's easy and very safe. http://www.openwall.com/phpass/ – Jonast92 Apr 21 '13 at 23:52

1 Answers1

3

Set the folder to where your file is stored to deny all and then using readfile you should be able to access it.

<?php
    if (!empty($_POST)) {
        $user = $_POST['user'];
        $pass = $_POST['pass'];

        if($user == "admin"
        && $pass == "admin")
        {
            $file = 'path/to/file';

            if (file_exists($file)) {
                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');
                header('Pragma: public');
                header('Content-Length: ' . filesize($file));
                ob_clean();
                flush();
                readfile($file);
                exit;
            }
        }
    }
?>

<form method="POST" action="">
    User <input type="TEXT" name="user"></input>
    Pass <input type="TEXT" name="pass"></input>
    <input type="submit" name="submit"></input>
</form>
dyelawn
  • 750
  • 5
  • 17
Matthew Camp
  • 866
  • 5
  • 9
  • I thought about using Apache with HTTP Auth, but modern browsers tend to cache the credentials, and I want to force the user to type the password each time they log in. – merlin2011 Apr 21 '13 at 23:53
  • Couldn't you use a header like: header("Cache-Control: no-store, no-cache, must-revalidate) – Matthew Camp Apr 22 '13 at 00:02
  • Unclear whether all the major browsers will actually obey that server directive. Also, I'm running PHP out of cgi-bin, which might further limit the use of such headers. – merlin2011 Apr 22 '13 at 00:07
  • I believe you can replace the include in the example you had in your question with a header to the path of your file. See edit in my answer. – Matthew Camp Apr 22 '13 at 00:15
  • Will this work if the path is not web-accessible though (so people can't just download it using the path)? – merlin2011 Apr 22 '13 at 00:18
  • Okay, I guess I needed to combine your answer with this one. http://stackoverflow.com/a/5641534/391161 – merlin2011 Apr 22 '13 at 00:23
  • If you edit your answer to include those three lines, it will match with my working implementation. – merlin2011 Apr 22 '13 at 00:25
  • 1
    Gotta love the good old copy+paste from the php docs: http://php.net/manual/en/function.readfile.php#example-2374 – dyelawn Apr 22 '13 at 00:31
  • Edited answer with tested script for what you need. Just make sure your directory is set to deny all. – Matthew Camp Apr 22 '13 at 00:35