PHP protected file downloads for your site's members

Hey, look! I just made a Google friendly entry title... And I did it because I want people to learn from the mistakes I made.

Suppose you have a website and you want to have some downloads available only to the members. Maybe you'll manually approve each member to protect your bandwidth and so on... What do you do? You'll most likely set up a members system in PHP (or integrate your downloads page with your exisiting members system) and then you'll write a script to check if the user is authenticated and / or has download rights and if yes pass him the file via the script. You do this "via the script" passing instead of a header redirect to the real location of the file because advanced users could note the real location of the file thus circumventing the protection.

If you have big files to protect (relative to your server's memory) don't make the same mistake I did. Do not use any PHP function that loads the file into the memory and than passes it on to the user. You'll expose the server your pages are hosted on to unwanted DoS (Denial of Service) risks. My client had some nice guy coming through an open proxy from Cambodia who hammered the server with 5 to 10 requests per second for software-download.php?id=435. What happened was that PHP tried to load 10 * 85 megs per second and I'll let you do the math and figure out how much it took it to run out of memory... I caught the bastard by activating Apache's mod_status module and watched what was happening in real time.

I'm still thinking about an easy solution for this problem, except splitting up the huge files with RAR or banning more than 1 connection from one user in an X minute interval which creates some database overhead.

Posted in PHP on February 14, 2005 at 1:57 PM EET
Comments

You could also use cookies or server side tracking of IP's to make sure nobody downloads more than X files at once. Some kind of semaphore with X slots.

Posted by Adi on February 14, 2005 at 6:22 PM EET

What's wrong with http authentication?

http://httpd.apache.org/docs/howto/auth.html#basic

Posted by Gabriel Radic on February 15, 2005 at 4:03 PM EET

How does the entire file ends up in memory?
I did, about 4 years ago, a PHP script that would check credentials and then read from the file and write to the user, copy&paste via a small buffer. Why load the entire file in memory?

Use readfile ( http://ro.php.net/manual/en/function.readfile.php )... or any of the other alternatives listed on that page.

Posted by Gabriel Mihalache on March 20, 2005 at 1:16 PM EET

P.S. You need to set the buffer/chuck size or just rought it out with fopen and friends.

Posted by Gabriel Mihalache on March 20, 2005 at 1:18 PM EET
Post a comment









Remember personal info?


Note Your e-mail will be kept private. If you leave a comment on an old(er) entry Movable Type might force it's moderation so I'll have to approve it before it appears.