Stop Hotlinking

  • keywords:
    • software
    • copyright
    • php
    • apache
    • htaccess
  • published:
  • updated:
  • Atom Feed

First, you may ask What is hotlinking? Hotlinking is when someone uses one of your images on their webpage. Usually this is very bad for two reasons:

It is this second point which is 'hotlinking'. Below are two examples of someone hotlinking my images. They are real examples and if you click on the previews you’ll get the full-sized image and so you can read the address bar and check them out if you want.

  1. 512x320 (66.0 KiB)
  2. 1,024x640 (200.9 KiB)
  3. 1,280x800 (222.8 KiB)
  1. 512x320 (86.0 KiB)
  2. 1,024x640 (275.5 KiB)
  3. 1,280x800 (339.9 KiB)

This article will show you how to stop the hotlinking of your images. This article has been written after I read a great article on the subject at A List Apart (called Smarter Image Hotlinking Prevention) and I felt that I could improve on it by simplifying the solution.

Firstly, one must edit the .htaccess file on your webserver. Now this is the solution that a quick Google search will turn up, but once this solution is implemented we have not finished, there is a final touch which needs to be done. So, in the root of your webserver create a file called .htaccess which contains these lines:

If the file already exists then just append these lines. If you are having difficulty creating this file then call it something else and edit it on your computer then upload it via FTP and rename it once it is on the server.

What this file does is only look at files which have extentions jpg, gif or png. Then, when someone tries to access one of these files it looks to see where the request is coming from. If the request is from one of your 'example domains' (which you can change to your own website), or if the HTTP Referer is empty, then the request can procede as normal. If not, then the request will get sent to /path/to/custom/script.php?src=/path/to/requested/image.jpg. Now, the user will not see this address, they will get the address that they want but the actual place where the code comes from will be that PHP script. As far as the user is concerned this is a totally transparent process - they will never know.

Now we need to create that PHP script and then we’re done. You’ll have to make sure that the link in the .htaccess points to the actual location of the PHP script we’re about to make. The PHP script should contain something like:

Now, a few things need to be explained so you can see how it works.

  1. The header("Content-type: text/html"); is very important. This tells the web browser that this file is a HTML file. This will stop the image being displayed straight away as the browser is expecting an image, so to be told it’s getting some text will throw a spanner in the works. Problem solved: image is not displayed.

  2. Now, the stuff about header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); is just telling the browser not to remember this page so that if it visits it again it’ll fetch it without using a cached version.

  3. Now, the rest is just a fancy way of displaying the image that the person wanted if they visit the page. This will only happen if the user visits the page on its own and it’s just a way to show your content, on your site. It contains a link to see the image fullsize. Now obviously this will have the same address, but as they will have clicked on a link from your own site then they’ll just get the image on it’s own. This is also why we put the anti-cache lines in as we don’t want the browser to remember the text bits.

The reason why this method should be used (and is better) than simple denials is that if someone puts a text link to your image on a website and then a user follows this link it will look to the .htaccess file as if it is being hotlinked and it will not display it - which is bad! Using this method stops your images being displayed on alien websites but still shows your image for visitors coming from those alien websites of their own accord.

To continue the worked example, this is what their pages look like after my solution has been implemented:

  1. 512x320 (63.6 KiB)
  2. 1,024x640 (184.2 KiB)
  3. 1,280x800 (180.7 KiB)
  1. 512x320 (89.6 KiB)
  2. 1,024x640 (259.6 KiB)
  3. 1,280x800 (254.9 KiB) see? No images! If a link was provided to one of the images then the HTTP Referer will also be the same as a hotlink and so it will trigger the PHP page, as we’ve already discussed above. The pages will then look like this:

  1. 512x320 (145.5 KiB)
  2. 1,024x640 (480.9 KiB)
  3. 1,280x800 (593.4 KiB)
  1. 512x320 (133.0 KiB)
  2. 1,024x640 (431.5 KiB)
  3. 1,280x800 (508.6 KiB)

...which show the preview image and a link to see the image on its own. I hope this helped!