views:

211

answers:

5

I have a downloads directory on a website where I store a bunch of different files for people to download (zip, exe, java, php, etc). The problem is that my website is written in PHP, so the web server, Apache, tries to execute the scripts instead of letting people download them. Without having access to Apache config (I'm on shared hosting), what is the easiest way to prevent Apache from executing scripts in a single directory?

I tried using mod_mime unsuccessfully. AddType doesn't work because (I'm guessing) a MIME type is already associated with PHP scripts. ForceType doesn't work because I store different types of files in the directory. Are there any other options?

+4  A: 

You could write a separate PHP script which sends the right Content-type header and then uses readfile() to pass through the contents of the PHP file without PHP actually executing them (and since Apache already passed off the request to PHP, it no longer cares). Just make sure you restrict it to only serving things out of that directory.

Amber
Most portable solution.
LiraNuna
+11  A: 

If you have sufficient permissions for that, putting the following line in a .htaccess file in the directory in which you don't want PHP script to be executed might do the trick :

php_flag engine off

(Just tested on my webserver, and I got the source of a PHP script -- which had not been executed)

Pascal MARTIN
+1 for this - assuming you have the permissions for it (which you probably do), this would likely be the ideal solution.
Amber
+1 - this answer is clearly superior.
gahooa
By far the easiest way to do what I need, but I may not end up using this method. Since I have some HTML in my script, browsers try render whatever they can and the result looks bad. Are there any magical means of forcing the server to also display my scripts as plain text?
MiseryIndex
Check out http://serverfault.com/questions/82505/how-can-i-set-apache-to-serve-files-as-text
Ciarán Walsh
@Ciarán: ForceType won't do any good because I have different types of files in a directory.
MiseryIndex
@self: Actually, you can use the AddType directive after turning of the PHP engine. Add `AddType text/plain .php` to the following line, and everything works like a charm!
MiseryIndex
+1  A: 

I think I have the solution for you. Check this out:

http://www.boutell.com/newfaq/creating/forcedownload.html

Basically, it says that you should have the following code in your php page:

<?php
header('Content-disposition: attachment; filename=whatever.php');
header('Content-type: text/html');
readfile('whatever.php');
?>

I made a sample here:

http://sotkra.com/test.php

This forces the 'download' file prompt where the file download is the whatever.php

Cheers

Sotkra
+1  A: 

You should have a download gateway script, such as download.php. It should take a query string argument which lists the file that needs downloaded.

That argument should be matched against a pre-existing ARRAY of accessible files (big security point there).

Then use:

<?php
$file = trim(isset($_GET['file']) ? $_GET['file'] : '');

$allow = array(
    'foo.php' => 'text/plain',
    'foo.jpg' => 'image/jpeg',
);    

if(! isset($allow[$file]))
   die('File not found.');

header('Content-Type: ' . $allow[$file]);
readfile($file);
gahooa
+3  A: 

I think the common solution to this is to give files the extension phps.

Pekka
Creative, but no, I want `php` ;-)
MiseryIndex