.htaccess to deny download except when query string has secret key

Posted in Articles

Tweet This Share on Facebook Bookmark on Delicious Digg this Submit to Reddit

Here is an mod rewrite rule that you can put in .htaccess file to not let anyone download files from the directory — except when the the direct access URL contain a query string with a secret key.

<IfModule mod_rewrite.c>
 RewriteEngine On
 RewriteCond %{QUERY_STRING} !secretkey=dsfkdkx3232
 RewriteRule (.*) - [F]
</IfModule>

Put this in .htaccess in the same directory that you want to protect on a Apache server.

The line …

RewriteRule (.*) – [F]

forbids download for everything.  The [F] is forbid.  The (.*) is everything.  Apache docs writes that the [F] flag will return 403 (forbidden) error.  And that the [L] flag (last rule flag) is implied when using [F].

The RewriteCond rule …

says apply that rule when the condition is met.  The condition being that when query string is not the secretkey as specified.

Here is doc on rewriting for query string conditions.

The effect is that if the directory say contains the file mybackup.zip, then direct access to the file via URL of say …

http://www.example.com/backups/mybackup.zip

will return a 403 server error and the file can not be accessed.

However, if the URL were …

http://www.example.com/backups/mybackup.zip?secretkey=dsfkdkx3232

then the file can be downloaded.

This comes in handy when you want the webapp (which knows the secret key) to access and download the file, but not anyone who stumbles upon it.

Would have been even better if you obfuscate the location and filename as in putting it as …

http://www.example.com/backups-33dskdkewo/mybackup-wej82392jvn.zip

If you use some web backup plugin in your content management system, check that it stores the backup in this fashion and protect direct URL access using similar technique.  Because a backup of a zip file not something you want anyone to get their hands on because it potentially can contain config files with database access passwords in plain text and other sensitive information.