protect guessing of URL downloads

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
jonners
Forum Newbie
Posts: 5
Joined: Mon Feb 16, 2004 6:37 pm

protect guessing of URL downloads

Post 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
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Post 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.
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
phait
Forum Commoner
Posts: 46
Joined: Wed Apr 07, 2004 4:41 am
Location: watford / leicester, UK

Post 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
User avatar
JayBird
Admin
Posts: 4524
Joined: Wed Aug 13, 2003 7:02 am
Location: York, UK
Contact:

Post by JayBird »

also, use htaccess to protect the directoie incase the direct link is found out. This will then not allow direct linking.

Mark
jonners
Forum Newbie
Posts: 5
Joined: Mon Feb 16, 2004 6:37 pm

I kind of understand....

Post 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 :)
User avatar
JayBird
Admin
Posts: 4524
Joined: Wed Aug 13, 2003 7:02 am
Location: York, UK
Contact:

Post 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
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Post by pickle »

Ya, exactly what ~bech100 and I said about the PHP file. Although, the .htaccess file should also work.
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
jonners
Forum Newbie
Posts: 5
Joined: Mon Feb 16, 2004 6:37 pm

Post by jonners »

thanks guys, I'll give this a go.
User avatar
JAM
DevNet Resident
Posts: 2101
Joined: Fri Aug 08, 2003 6:53 pm
Location: Sweden
Contact:

Post 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.
Post Reply