0

I am running a website which has a number of zip files in a single folder.

I'd like people to be able to access these from download links on the website (which will be behind a log-in) but I want to make sure that they can't be downloaded by typing the URL of the zip files directly.

So I presume this needs to be done with htaccess - and some sort of deny all rule, with an exception of my domain. Would this be correct?

Right now, my file contains this (with my actual domain replaced by "domain"):

SetEnvIfNoCase Referer "^http://domain.com/" locally_linked=1
SetEnvIfNoCase Referer "^http://domain.com$" locally_linked=1
SetEnvIfNoCase Referer "^http://domain.com/" locally_linked=1
SetEnvIfNoCase Referer "^http://domain.com$" locally_linked=1
SetEnvIfNoCase Referer "^$" locally_linked=1
<FilesMatch "\.(zip)$">
  Order Allow,Deny
  Allow from env=locally_linked
</FilesMatch>

Can anybody shed any light on why this might not be working?

I'm on a shared host (Dreamhost) :/ - but I'm presuming this doesn't make much difference.

Thanks.

alexcowles
  • 37
  • 1
  • 7

3 Answers3

0

What you are trying to do is prevent hotlinking. You can't really prevent it from happening but you can deny downloads from other referrers.

Add the following to your .htaccess file, replacing example.com with your domain. If you want to protect other file formats add them where it says zip, for example (zip|rar)

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)example.com/.*$ [NC]
RewriteRule \.(zip)$ - [F]

If you want to serve alternative content (Like a page saying that you must login first) use:

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)example.com/.*$ [NC]
RewriteRule \.(gif|jpg)$ http(s)?://www.example.com/alternate.html [R,L]
aurbano
  • 3,324
  • 1
  • 25
  • 39
  • Very useful, thank you. Is there a way to amend/edit this to stop people also guessing the URL of the zip files and just entering that directly in to their browser bar to initiate a download? – alexcowles Mar 24 '14 at 09:32
  • This will also prevent direct access. The only way this will allow access to zip files is if their referrer header contains your domain. And that will only happen (normally) when following a link in your website. – aurbano Mar 24 '14 at 09:35
  • I can't access the file because of my company's firewall, try again with the code in my answer. According to this question it should work: http://stackoverflow.com/questions/10236717/htaccess-how-to-prevent-a-file-from-direct-url-access – aurbano Mar 24 '14 at 09:48
0

I have something similar but using mod_rewrite and use this code

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?yourdomain.com [NC]
RewriteRule \.(zip)$ - [NC,F,L]
Sal00m
  • 2,938
  • 3
  • 22
  • 33
  • This seems to stop people linking to the files - which is great, thank you. It doesn't stop me typing in the direct URL in to my browser however - is there a way to combat that? (someone guessing the name of the file for example) – alexcowles Mar 24 '14 at 09:30
  • This code validates referer, so if the referer is not from your domain then the file will not be downloaded, even if you type direct url – Sal00m Mar 24 '14 at 09:37
  • AWESOME! Thank you. It didn't seem to work for me when I tried that, but great to hear :) – alexcowles Mar 24 '14 at 09:49
0

You can use headers to do this:

// set example variables
$filename = "file_to_download.zip";
$filepath = "/var/www/domain/path_to_download/";

// http headers for zip downloads
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"".$filename."\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filepath.$filename));
ob_end_flush();
@readfile($filepath.$filename);

In this example you can add more login, for example is user logged.

IceManSpy
  • 1,078
  • 1
  • 13
  • 35