I recently wanted to protect some files from unauthorised download on a WordPress site, but still allow authorised users to easily access the files.
The simplest solution I found was to put the files in a custom directory, place the links on a WordPress password-protected page, and use a .htaccess file as a basic deterrent to casual downloads. The rules below check the request’s referrer and whether its cookie header contains wp-postpass. They do not validate the page password or a WordPress login session.
Here is the step-by-step guide.
1. Make a new directory on your site and upload the files you want to protect to this directory (using ftp or scp). Make sure you choose a directory name that is hard to guess. I would recommend a random string — something like “vg4thbspthdbd8th” — just don’t use this exact string!
mkdir /path_to_protected_directory/
2. ssh into the server and create a .htaccess file in the protected directory using nano.
sudo nano /path_to_protected_directory/.htaccess
3. Copy and paste the following text into the .htaccess file.
Options -Indexes
php_flag engine off
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?yourwebsite.com [NC]
RewriteCond %{HTTP_COOKIE} !^.*wp-postpass.*$ [NC]
RewriteRule \.(zip|rar|exe|gz)$ - [NC,F,L]
4. Change the yourwebsite.com to your website’s actual name. You should also change the RewriteRule line to suit the content you wish to protect. Just add the extensions of any file type you want to protect from unauthorised download.
That is it.
The major limitation is that both the referrer and cookie headers can be supplied by the requester. These rules are not an authentication or authorisation check.
Non-obvious directory and file names can make links harder to guess, but they do not provide access control. Anyone who obtains a download URL may be able to access it by supplying those headers.
Use this only as a casual download deterrent. Files requiring genuine access control should be served through a handler that validates the user’s session or password and permission for each download.
