Page 1 of 1

file system security at a user level?

Posted: Mon Aug 20, 2007 4:11 pm
by davisaggie
I am trying to set up a new feature on my extranet site. The new feature will allow users to log-in and view links to reports (PDF format) that are specific to that user. I have a pretty good idea on how to do this using either ExpressionEngine (a php based CMS) or just straight PHP. What I am a little lost on right now is securing the files. The restrictions on file access are:

- I need to have the new part of my site not be accessable unless the person is signed in
- the signed in user can only access their own reports/files, i.e. User A cannot see User B's reports
- the link to the individual pdfs can only be used if a person is logged in, i.e. If User A signs on once, then copies the link to his report, he then cannot e-mail that link to another person and have them be able to pull up the report.

Is there a way to set all this up through PHP, or do I need to do this at the server level or somewhere else? I have never had to do something like this with PHP so any direction would be much appreciated.

Posted: Mon Aug 20, 2007 4:32 pm
by feyd
Don't give them links to the actual files. Instead, pass it through a handling script.

Posted: Mon Aug 20, 2007 7:07 pm
by davisaggie
feyd wrote:Don't give them links to the actual files. Instead, pass it through a handling script.
Feyd, how would I do that?

Digging around some I have found that I can use Appache to control at the directory level access to the different reports, but is there a way to trap the user id provided to appache during authentication checking?

Posted: Mon Aug 20, 2007 9:55 pm
by superdezign
Handling script. Like a PHP script to serve the files. PHP can access more of the server's file structure than the users.

Posted: Tue Aug 21, 2007 10:27 am
by davisaggie
superdezign wrote:Handling script. Like a PHP script to serve the files. PHP can access more of the server's file structure than the users.
Could you give an example of a handling script, or point me in the right direction? I've never heard of them and most of my PHP experience has been with dealing with the output from Forms and accessing MySQL. When it comes to file handling I'm a total n00b.

Posted: Tue Aug 21, 2007 10:31 am
by VladSun

Code: Select all

if ($_SEESION['logged'])
{
            $filename = 'dummy.zip';
            $filename = realpath($filename);

            $file_extension = strtolower(substr(strrchr($filename,"."),1));

            switch ($file_extension) {
                case "pdf": $ctype="application/pdf"; break;
                case "exe": $ctype="application/octet-stream"; break;
                case "zip": $ctype="application/zip"; break;
                case "doc": $ctype="application/msword"; break;
                case "xls": $ctype="application/vnd.ms-excel"; break;
                case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
                case "gif": $ctype="image/gif"; break;
                case "png": $ctype="image/png"; break;
                case "jpe": case "jpeg":
                case "jpg": $ctype="image/jpg"; break;
                default: $ctype="application/force-download";
            }

            if (!file_exists($filename)) {
                die("NO FILE HERE");
            }

            header("Pragma: public");
            header("Expires: 0");
            header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
            header("Cache-Control: private",false);
            header("Content-Type: $ctype");
            header("Content-Disposition: attachment; filename=\"".basename($filename)."\";");
            header("Content-Transfer-Encoding: binary");
            header("Content-Length: ".@filesize($filename));
            set_time_limit(0);
            @readfile("$filename") or die("File not found.");
}
else
{
            ?>
             <html><body>You have to login first!</body></html>
            <?php
}

Posted: Tue Aug 21, 2007 11:01 am
by davisaggie
Vlad, thanks for the code sample. A couple questions though:

1) Do I need the case statement if I know all the files that are going to be accessed are of the same file type?
2) Do I need to create a separate page with this code on it for each file that can be accessed, or is there a way to put this script on a single page and pass the file name to it some how?

Thanks to all for the advice so far.

Posted: Tue Aug 21, 2007 2:41 pm
by VladSun
davisaggie wrote:Vlad, thanks for the code sample. A couple questions though:

1) Do I need the case statement if I know all the files that are going to be accessed are of the same file type?
2) Do I need to create a separate page with this code on it for each file that can be accessed, or is there a way to put this script on a single page and pass the file name to it some how?

Thanks to all for the advice so far.
1) It's up to you and your application.
2) No. Use $_GET/$_POST instead.

Posted: Thu Aug 23, 2007 11:12 pm
by toasty2
I'd like to point out that VladSun misspelled session in his code.

Posted: Wed Sep 05, 2007 1:06 pm
by davisaggie
VladSun wrote:
davisaggie wrote: 2) Do I need to create a separate page with this code on it for each file that can be accessed, or is there a way to put this script on a single page and pass the file name to it some how?
2) No. Use $_GET/$_POST instead.
Is it possible to use either $_GET or $_POST if I am not using a form, but a link to direct users to a handling script that will load the file name corresponding to the link?

E.G.

page 1 has two links:

File1
File2

When the user clicks File1 they are directed to a page with the file handling script above and File1 gets loaded. If they click on the link for File2 they are taken to the same script, but now file2 gets loaded instead.

Would this method work if the files were placed outside of the web directory? Currently my base web directory is C:\web\htdocs, but I would like to place the files in C:\files for example as an extra layer of protection.

Posted: Wed Sep 05, 2007 1:22 pm
by VladSun
Yes, it is possible.
Use links like this: http://server.com/file_handler.php?fileid=345

I strongly recommend you not to use file names. I.e. links like this: http://server.com/file_handler.php?file ... cument.pdf. It is very often vulnerable to attacks.

Instead, use some kind of mapping - e.g. array of file names and link them by their index, like I do in my first example link above.
You can read th eindex by GET['fileid']

Posted: Thu Sep 06, 2007 10:32 pm
by Z3RO21
superdezign wrote:Handling script. Like a PHP script to serve the files. PHP can access more of the server's file structure than the users.
Superdezign has the right idea this is what I do. Users have only one access point / have access to only one file to the php system. The rest is outside of their reach.