psst.. this blog is on hiatus.

Selective hotlinking prevention through .htaccess

Purpose of this dorky little tutorial

This tutorial describes how to selectively limit hotlinking on your website. You can block hotlinking of most of the images on your website, but allow certain directories to be hotlinked, since this can be useful for you (the website owner).

UPDATE: I’ve published an updated tutorial that improves upon the approach outlined here. I recommend it over this approach. See Preventing image hotlinking: An improved tutorial.

Overview of hotlinking

I’ve read a lot of tutorials on the Web about hotlinking. It’s a common problem—users steal other sites’ bandwidth by directly linking to images on the external website. Hotlinking is particularly a problem with the many forums and message boards on the Web that allow users to insert images. These can’t be kept on the host site, so the user hotlinks them when creating the <img> tag.

AltLab’s useful site defines hotlinking as:

Bandwidth theft or “hotlinking” is direct linking to a website’s files (images, video, etc.). An example would be using an <IMG> tag to display a JPEG image you found on someone else’s web page so it will appear on your own site, journal, weblog, forum posting, etc.

This site also provides a “test” to tell whether your images can be hotlinked. But there’s a simple way to prevent hotlinking, and that’s through the use of regular expressions in your .htaccess file. Using the mod_rewrite module of Apache, you give your Web server this instruction: “If the image being loaded has a referrer, or source URL, that is different from my website, don’t allow it.”

One piece of information that’s lacking from many of the tutorials on the Web is how best to go about structuring your .htaccess files. That is, often you’ll want to limit hotlinking from most of your images, but allow it on others, such as when you (the all-powerful website owner) want to hotlink images from your own site. If you prevent hotlinking of all images from your site, you’ve screwed yourself! So you have to know how to do it selectively, and you have to know a small bit about how mod_rewrite works.

Before you start, make a game plan

Let’s say you’ve got the website http://www.dorkytutorial.com and you want to prevent hotlinking of its images. However, you want to be able to use images from http://www.dorkytutorial.com/vacation/ on another site. Here is what you need to do:

  1. Put your main anti-hotlinking rules in http://www.dorkytutorial.com/.htaccess, i.e. at the root-level
  2. “Turn off” the anti-hotlinking in another .htaccess at http://www.dorkytutorial.com/vacation/.htaccess

Ready, set, go? All right.

Blocking hotlinking site-wide

Many variations exist on the specific regular expressions you can write, but they all accomplish the same thing. In the actual rewrite component, you can either throw the client a FORBIDDEN (meaning the image ain’t here), or you can redirect it to another image (either something bitching about their hotlinking, or something suitably offensive).

Here’s my anti-hotlinking .htaccess instructions:

RewriteEngine    on
RewriteCond    %{HTTP_REFERER} !^$
RewriteCond    %{HTTP_REFERER} !^http://([-a-z0-9]+\.)?dorkytutorial\.com [NC]
RewriteRule    \.(gif|jpe?g|png)$ - [F,NC,L]

Lines 2 and 3 establish the conditions for blocking an image from being rewritten. Line 2 says, to block client loading of the image, “the referrer must be not null.” Line 3 says, to block client loading of the image, “the referrer must not come from any domain of dorkytutorial.com”—and the “NC” part makes that check not case sensitive.

Line 4 checks that the filetype is a GIF, JPEG, JPG, or PNG, and if so, sends an HTTP 403 response of FORBIDDEN to the client (that’s the “F” part on the end). Also, the “L” flag means that this is the last rule to process, so that if an HTTP request matches this rule, don’t bother stepping through any further rewrite rules in the .htaccess. This one is mostly for effiency’s sake.

Selectively allowing hotlinking

Okay, now we’ve blocked hotlinked site-wide at dorkytutorial.com. But what about allowing it in the vacation/ directory? To do that, we need to invoke the RewriteEngine again, because as Apache serves files from the vacation/ directory, it will “override” the rewrites of the root-level .htaccess with vacation/.htaccess. If we invoke a dummy rule that does nothing to stop hotlinking, we’ll be set. And here it is—place this in http://www.dorkytutorial.com/vacation/.htaccess to override the main anti-hotlinking instructions:

RewriteEngine on
RewriteRule ^.*$ -

Big props to Ten from my work and WebPimps’ .htaccess Code Tricks & Tips for alerting me to this.