This is a discussion on Download files outside DocumentRoot Dir within the PHP General forums, part of the PHP Programming Forums category; Hi, i'm trying to find a good solution to this problem. I want download files from a directory outside ...
|
|||||||
| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
|
|||
|
Hi,
i'm trying to find a good solution to this problem. I want download files from a directory outside DocumentRoot. This files cannot be downloaded through direct url like http://site/test.zip. It must be downloaded after user login. I know i can do that using some functions like fread() + fopen() or readfile(), than i would echo file buffer to browser with correct headers. But, reading then dumping file to browser is a big problem to server. I've made one test that shows me i will "eat" 1.8% of RAM (i've used "ps aux" at Linux, in a server with 2Gb of RAM) to download a 30Mb file at 60kb/s speed. So, imagine what a dump-php-script can do with 50 to 100 concurrently downloads. Probably i will need 1 TeraByte of RAM to provide downloads ;) Theres my question now. Is there other way to protect files against direct downloading? (Obligating users to login and denying direct-url's). I also know i can check referer by using Mod_Rewrite at Apache. But it isn't secure, since referer cannot be sent or be fake. Please, help me ;) Thank you ! -------- Script i used to test: <? $url = "test.tar.gz"; header('Content-Description: File Transfer'); header('Content-Type: application/force-download'); header("Content-Disposition: attachment; filename=\"".basename($url)."\";"); header('Content-Length: ' . filesize($url)); @readfile($url) OR die(); ?> |
|
|||
|
Ramiro wrote:
> Hi, > i'm trying to find a good solution to this problem. I want download files > from a directory outside DocumentRoot. > > This files cannot be downloaded through direct url like > http://site/test.zip. It must be downloaded after user login. > > I know i can do that using some functions like fread() + fopen() or > readfile(), than i would echo file buffer to browser with correct headers. > But, reading then dumping file to browser is a big problem to server. http://ie2.php.net/fpassthru Kae |
|
|||
|
At 01:44 AM 9/25/2006, Ramiro wrote:
>Hi, >i'm trying to find a good solution to this problem. I want download files >from a directory outside DocumentRoot. > >This files cannot be downloaded through direct url like >http://site/test.zip. It must be downloaded after user login. > >I know i can do that using some functions like fread() + fopen() or >readfile(), than i would echo file buffer to browser with correct headers. >But, reading then dumping file to browser is a big problem to server. > >I've made one test that shows me i will "eat" 1.8% of RAM (i've used "ps >aux" at Linux, in a server with 2Gb of RAM) to download a 30Mb file at >60kb/s speed. So, imagine what a dump-php-script can do with 50 to 100 >concurrently downloads. Probably i will need 1 TeraByte of RAM to provide >downloads ;) > >Theres my question now. Is there other way to protect files against direct >downloading? (Obligating users to login and denying direct-url's). > >I also know i can check referer by using Mod_Rewrite at Apache. But it isn't >secure, since referer cannot be sent or be fake. > >Please, help me ;) > >Thank you ! >-------- >Script i used to test: ><? >$url = "test.tar.gz"; > >header('Content-Description: File Transfer'); >header('Content-Type: application/force-download'); >header("Content-Disposition: attachment; filename=\"".basename($url)."\";"); >header('Content-Length: ' . filesize($url)); >@readfile($url) OR die(); >?> > >-- >PHP General Mailing List (http://www.php.net/) >To unsubscribe, visit: http://www.php.net/unsub.php This is the contents of a script used to fetch .swf's. The script is called from a Flash movie. $filenam = $_REQUEST["filenam"]; if ($filenam){ $contents = file_get_contents( "../above_root/" . $filenam ); echo $contents; }else{ echo "Not found"; } HTH - Miles -- No virus found in this outgoing message. Checked by AVG Free Edition. Version: 7.1.405 / Virus Database: 268.12.8/455 - Release Date: 9/22/2006 |
|
|||
|
Ramiro wrote:
> Hi, > i'm trying to find a good solution to this problem. I want download files > from a directory outside DocumentRoot. > > This files cannot be downloaded through direct url like > http://site/test.zip. It must be downloaded after user login. > > I know i can do that using some functions like fread() + fopen() or > readfile(), than i would echo file buffer to browser with correct headers. > But, reading then dumping file to browser is a big problem to server. > > I've made one test that shows me i will "eat" 1.8% of RAM (i've used "ps > aux" at Linux, in a server with 2Gb of RAM) to download a 30Mb file at > 60kb/s speed. So, imagine what a dump-php-script can do with 50 to 100 > concurrently downloads. Probably i will need 1 TeraByte of RAM to provide > downloads ;) > > Theres my question now. Is there other way to protect files against direct > downloading? (Obligating users to login and denying direct-url's). > > I also know i can check referer by using Mod_Rewrite at Apache. But it isn't > secure, since referer cannot be sent or be fake. > > Please, help me ;) > > Thank you ! > -------- > Script i used to test: > <? > $url = "test.tar.gz"; > > header('Content-Description: File Transfer'); > header('Content-Type: application/force-download'); > header("Content-Disposition: attachment; filename=\"".basename($url)."\";"); > header('Content-Length: ' . filesize($url)); > @readfile($url) OR die(); > ?> > What you can do is put the downloads in a separate directory actually in your webroot. Then, use a .htaccess file to include a PHP file which checks for authentication. ie: File in : /var/www/htdocs/downloads/file.zip Accessible by: http://site/downloads/file.zip ..htaccess: php_value auto_prepend_file "/var/www/htdocs/authenticate.php" authenticate.php would theoretically have some code to check that the user is authenticated, and if not, redirect to a login screen before any headers are sent to the user. -- Christopher Weldon, ZCE President & CEO Cerberus Interactive, Inc. cweldon@cerberusonline.com 979.739.5874 |
|
|||
|
On 2:36 pm 09/25/06 "Ramiro Cavalcanti" <ramiro@hostcom.com.br> wrote:
> Hi Christopher, > at first, thank you for your answer. > > I'd like to know if it's possible use this when php is running like > cgi (php-suexec). I've put this code at httpd.conf at <module php>, > then tryed to use it at .htaccess, but without successs. > > Thank you again. > Oh, in that case, you most definitely can't use the .htaccess conditions. PHP will have issues if you are running php-suexec. I'll see if I can think of any other ways around this, but php-suexec definitely limits your usage for this simple fix right now. -- Chris Weldon |
|
|||
|
On Sun, September 24, 2006 11:44 pm, Ramiro wrote:
> i'm trying to find a good solution to this problem. I want download > files > from a directory outside DocumentRoot. > > This files cannot be downloaded through direct url like > http://site/test.zip. It must be downloaded after user login. > > I know i can do that using some functions like fread() + fopen() or > readfile(), than i would echo file buffer to browser with correct > headers. > But, reading then dumping file to browser is a big problem to server. > > I've made one test that shows me i will "eat" 1.8% of RAM (i've used > "ps > aux" at Linux, in a server with 2Gb of RAM) to download a 30Mb file at > 60kb/s speed. So, imagine what a dump-php-script can do with 50 to 100 > concurrently downloads. Probably i will need 1 TeraByte of RAM to > provide > downloads ;) Which did you use? readfile() or fopen/fread Because readfile() probably WILL cause that problem. But fopen/fread with a small buffer will allow many more concurrent downloads to "share" the RAM, but will also use as much RAM as is available, if nothing else is going on... I suspect your test is flawed, in other words. :-) > > Theres my question now. Is there other way to protect files against > direct > downloading? (Obligating users to login and denying direct-url's). Well, there's HTTP Authentication. There's time-specific URLs. There's all kinds of ways to protect a directory and require login... > I also know i can check referer by using Mod_Rewrite at Apache. But it > isn't > secure, since referer cannot be sent or be fake. > header('Content-Description: File Transfer'); > header('Content-Type: application/force-download'); > header("Content-Disposition: attachment; > filename=\"".basename($url)."\";"); Bogus, bogus, bogus. Please read this rant: http://richardlynch.blogspot.com/ > header('Content-Length: ' . filesize($url)); > @readfile($url) OR die(); Yup, readfile() That's a big difference right there... fopen/fread != readfile -- Like Music? http://l-i-e.com/artists.htm |
|
|||
|
On Mon, September 25, 2006 7:52 am, Miles Thompson wrote:
> $filenam = $_REQUEST["filenam"]; > if ($filenam){ > $contents = file_get_contents( "../above_root/" . > $filenam ); > echo $contents; > }else{ > echo "Not found"; > } I certainly hope this is not ALL of the script... Imagine, if you will, that somebody surfs to this URL: http://example.com/above_script.php?.../../etc/passwd By the rules of Linux, they've just downloaded your passwd file, which has all your usernames in it. That's a Bad Thing, as they then can look for an easy password in those accounts. Sanitize your data! PS Not to mention that file_get_contents() will suck the ENTIRE 60Mb file into RAM, which is exactly what the OP needs to avoid... :-) -- Like Music? http://l-i-e.com/artists.htm |
|
|||
|
On Mon, September 25, 2006 3:57 pm, Christopher Weldon wrote:
> On 2:36 pm 09/25/06 "Ramiro Cavalcanti" <ramiro@hostcom.com.br> wrote: >> Hi Christopher, >> at first, thank you for your answer. >> >> I'd like to know if it's possible use this when php is running like >> cgi (php-suexec). I've put this code at httpd.conf at <module php>, >> then tryed to use it at .htaccess, but without successs. >> >> Thank you again. >> > > Oh, in that case, you most definitely can't use the .htaccess > conditions. > PHP will have issues if you are running php-suexec. > > I'll see if I can think of any other ways around this, but php-suexec > definitely limits your usage for this simple fix right now. If you *want* that ugly HTTP Auth popup box, you can search on php.net for code to do that. If not, you can take that code, and replace the HTTP challenge with a simple login form. If they aren't logged in, the download just doesn't go... -- Like Music? http://l-i-e.com/artists.htm |
|
|||
|
On 9/24/06, Ramiro <ramiro@hostcom.com.br> wrote:
> Hi, > i'm trying to find a good solution to this problem. I want download files > from a directory outside DocumentRoot. This is a standard procedure. > > This files cannot be downloaded through direct url like > http://site/test.zip. It must be downloaded after user login. This will need some sort of rewrite or 404 handling on the webserver level > > I know i can do that using some functions like fread() + fopen() or > readfile(), than i would echo file buffer to browser with correct headers. > But, reading then dumping file to browser is a big problem to server. I readfile() about 10 6mb files per-second, and havn't had any issues with performance. > > I've made one test that shows me i will "eat" 1.8% of RAM (i've used "ps > aux" at Linux, in a server with 2Gb of RAM) to download a 30Mb file at > 60kb/s speed. So, imagine what a dump-php-script can do with 50 to 100 > concurrently downloads. Probably i will need 1 TeraByte of RAM to provide > downloads ;) Provide your tests, and exactly what version of php you have. a read file or a fopen/fread wont uses that much memory unless you dont specifly a length or specify a rather large amount for the length param for fread() > > Theres my question now. Is there other way to protect files against direct > downloading? (Obligating users to login and denying direct-url's). Yes. > > I also know i can check referer by using Mod_Rewrite at Apache. But it isn't > secure, since referer cannot be sent or be fake. you can check it without mod_rewrite. I think you meant to say 'it isn't secure, since the referrer can be fake or not even sent' So yes, this is true, this is not a security mechanism. Curt. |
|
|||
|
On Tue, September 26, 2006 6:29 pm, Curt Zirzow wrote:
>> This files cannot be downloaded through direct url like >> http://site/test.zip. It must be downloaded after user login. > > This will need some sort of rewrite or 404 handling on the webserver > level Au contraire, my good friend. $_SERVER['PATH_INFO'] and judicious usage of ForceType is much simpler and less stressful than mod_rewrite and 404 handling :-) I used mod_rewrite exactly once. Man, that was painful... -- Like Music? http://l-i-e.com/artists.htm |