Page 1 of 1

protect guessing of URL downloads

Posted: Wed Apr 14, 2004 9:15 am
by jonners
Hi,

I am developing a client section of a website and once they log in they will be displayed with a list of pdf's they can download. These URL's are pulled from the mySql DB, e.g.:

http://www.company.com/myClient/myClientPDF1.pdf
http://www.company.com/myClient/myClientPDF2.pdf

The deisgn of the system is such that an administrator can add 'clients' therefore creating a new directory e.g.

http://www.company.com/myNewClient/myClientPDF1.pdf
http://www.company.com/myNewClient/myClientPDF2.pdf

How can I ensure that client's can't 'guess' the URL's for other clients, as they will probably know the names in their industry?

Is a possible solution to use a random directory name by encrypting the client name and use that as a dirtectory name when creating a new client?

http://www.company.com/nj8777hag/myClientPDF1.pdf
http://www.company.com/nj8777hag/myClientPDF2.pdf

Then the php scripts will know which directory to look for.

Thanks,

Jon

Posted: Wed Apr 14, 2004 9:50 am
by pickle
My first guess would be to remove the direct link to the PDFs. You could make a PHP page that checks a session (to ensure only legitimate people are accessing the page), then spit out some headers to make it look like a PDF, then spit out some more headers to load the PDF. The result would be that only the URL from the PHP page would be visible.

Posted: Wed Apr 14, 2004 11:21 am
by phait
FWIW, I agree with pickle, better to have some sort of authentication system if the data is that valuable or important.
Your encrypted directory names are not exactly user friendly to the client either... can you imagine them trying to remember that url when they maybe haven't got access to their email for whatever reason.

hth

Posted: Wed Apr 14, 2004 11:23 am
by JayBird
also, use htaccess to protect the directoie incase the direct link is found out. This will then not allow direct linking.

Mark

I kind of understand....

Posted: Wed Apr 14, 2004 11:42 am
by jonners
OK, so I understand the idea of having authentication. They will have a session started when they log in, and can only see pages relevant to themselves by checking their session matches with the relevant pages etc.

But, when they click to download a pdf, they will click on a link similar to this:

http://www.englandhockey.co.uk/core_fil ... nload1.pdf

This will then download their pdf. Now assuming that in the above example, /core_files/ could be a client named /myClient/ but how can I ensure that they don't change the /myClient/ directory to /guessedClientName/fileDownload1.pdf and therefore download a file not intended for them?

I would like to keep fairly consistant naming conventions for client and files. There in lies the problem.

I found an example of what I would like to do on this page: http://www.21code.com/alfgate/index.php

Click on this http://www.21code.com/alfgate/download/picture.gif and you are denied, but the image show in the page above.

Hope this makes sense :)

Posted: Wed Apr 14, 2004 11:48 am
by JayBird
hwat you do is store the urls to the files in a db, then create a php file that send them the file they request.

What they will see in the URL is http://www.yoursite.com/download.php and not the url to the file

Mark

Posted: Wed Apr 14, 2004 12:54 pm
by pickle
Ya, exactly what ~bech100 and I said about the PHP file. Although, the .htaccess file should also work.

Posted: Wed Apr 14, 2004 1:09 pm
by jonners
thanks guys, I'll give this a go.

Posted: Wed Apr 14, 2004 1:44 pm
by JAM
pickle wrote:Ya, exactly what ~bech100 and I said about the PHP file. Although, the .htaccess file should also work.
This is very much taken out of a previous post I made thats not (yet) visible to the regular users of this forum. It's a part of a FileDownloading FAQ that needs to be revised by others. However, I can post some of the code within that to give you a brief guide of what to look for...

Code: Select all

header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");                   // past date 
            header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");      // always modified 
            header("Cache-Control: no-store, no-cache, must-revalidate");       // cache HTTP/1.1 
            header("Cache-Control: post-check=0, pre-check=0", false); 
            header("Pragma: no-cache");                                         // cache HTTP/1.0 
            header("Cache-Control: private");                                   // IE6 bug fix 
/*
You need to edit this part ($ctype) to reflect the MIME of the file offered to download. substr() on the filename to get the extension combined with switch() is one idea...
*/
            header("Content-Type: $ctype");                                     // the filetype 
            header("Accept-Ranges: bytes"); 
            header("Content-Disposition: attachment; filename=$thefile");       // the filename from the URI 
            header("Content-Transfer-Encoding: binary");                        // we want it in binary 
            header("Content-Length: ".filesize($thefile));
            $fp = fopen($thefile, 'rb'); 
            $buffer = fread($fp, $filesize); 
            fclose ($fp); 
            echo $buffer; // "send" the file 
            exit(); 
        } 
    }
As mentioned, the variables nedes some editing, how and where the file is selected, but the bigger part to initiate a filedownload usig php is there.

Hope that helped some.