PreventHotlinking

Summary: Prevent hotlinking of uploaded files
Version:
Prerequisites:
Status:
Maintainer: Ian MacGregor
Categories: Uploads Security

Questions answered by this recipe

Question

How do I protect uploaded files against hotlinking?

Answer

Hotlink protection can be obtained by adding code to a .htaccess file in the uploads directory and a test statement to the local config.php file. This recipe is a result of items learned from Pm

What is Hotlinking?

Hotlinking is when a web site is linking directly to images or other files that are served from another site. Hotlinking can be considered bandwidth theft, because images served on the page are remotely hosted on the owners page. As visitors arrive to view the page, the remote host has to conjure up the images for viewing which consumes additional bandwidth of the image owners site. The following steps will illustrate how to prevent such hotlinking.

Step 1: The .htaccess file
Add the following to a .htaccess file in the uploads directory - create the file if it doesn't exist.

Order Deny,Allow
Deny from all
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://(www\.)?yoursite\.com [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule \.(gif|jpg|png|jpeg|bmp)$ - [NC,F]

Change "yoursite\.com" with the url of your site, but the backslash "\" must remain because the dot "." needs to be escaped. This will prevent hotlinking of files with ".gif .jpg .png .jpeg .bmp" extensions, you can add your own extensions as well. The above code will yield a 404 error (ie. file not found) and will show a broken image icon on the hotlinker's page. This is the simplest way as it is fast and requires little bandwidth.

Or you can display a custom "locked" or "error" image instead of sending a 404 error by creating and uploading your own custom "locked" or "error" graphic and replace the last line in the above code with:

RewriteRule \.(gif|jpg|png|jpeg|bmp)$ lock.gif [L,NC]

This assumes "lock.gif" is the filename of your custom graphic.

Step 2: The local config.php file
Add the following test statement to your local config.php file.

if ($action == 'download' && !preg_match('!^http://www.yoursite.com!', @$_SERVER['HTTP_REFERER'])) exit();

The above test statement must be one line and will block downloads to sites other than www.yoursite.com. Note that the backslash "\" is not necessary here. This test statement is necessary because ?action=download bypasses .htaccess. I placed the test statement just below the $EnableUpload = 1; line in my local/config.php file and it works.

Step 3: Testing for hotlink prevention
Clear your browser cache for this test. You should now open your wiki, right-click on a graphic, choose "copy location" (or whatever your browser uses to copy an image location), paste that location into a test html file (or the browser location box). Upon loading the url, you should see either a broken image graphic or a custom graphic depending on the method you used in Step 1 above.

Notes

It is considered bad practice to send hotlinkers to another site that you don't control because the resulting site is wasting their bandwidth due to having to deal with people hotlinking your files.

See Also

Contributors

Comments