Welcome to Dagon Design. In addition to free scripts, WordPress plugins, and articles, we offer a variety of services including custom theme design, plugin creation, and PHP scripting. Contact me for more information.

Updated Saturday, June 4th, 2005 at 6:18pm

Hotlink Protection with .htaccess

If you host a website, you have most likely been the victim of hotlinking at one time or another. Hotlinking is when someone displays your images (or other media) on their website by directly linking to your server. This means they get to display your files while your bandwidth is being used. Luckily, it is easy to prevent with the help of the .htaccess file. This article will show some of the better methods to use to stop hotlinking while keeping your server running smoothly.

An example

Once someone found a large image on my site that they thought would make a good avatar on their forum. They linked to my server for the image, and even though it was shrunk down on the forum pages, it was still downloading the full size (over 200KB). This person had a lot of posts and it was a very heavily used forum. It ended up using about 100 Megs a day of bandwidth, or about 3 Gigs a month! That was when I decided to start using hotlink prevention.

Requirements

This article covers hotlink protection for the Apache web server. If you are running IIS, much the same can be accomplished using commercial software such as ISAPI Rewrite.

You may have to contact your hosting service or just experiment to see if you are able to use the .htaccess file. The .htaccess file is simply a text file which contains directives (configuration settings) for the Apache web server. It is easy to create if you do not have one already, and it is generally located in the root directory of your server. Any settings in this file will apply to all sub-directories (unless told otherwise – more on that later).

If you prefer to use the primary Apache configuration file (httpd.conf) for your server settings, everything in this tutorial can be accomplished much the same way.

A few notes on the code

This article will cover the two main methods of hotlink prevention: Image replacement and ‘403 Forbidden’ responses. You may have seen hotlink protection code which redirects users to a specified web page, but this will most certainly not work . This is the equivalent of placing a URL into an <img> tag, and it will do nothing more than cause problems.

If you want hotlinks to take visitors to your site, it is best to simply return a ‘403 Forbidden’ response and create nice custom error pages. A standard error page will generally just cause the visitor to close the window, but a well-made custom error page can give the visitor information about the site, and links to the main sections. They will be much more likely to visit your site because of this.

Explanations of the code samples are given below, as well as some basic information on flags and other options. For a full explanation of everything you can do with the .htaccess file, I recommend taking a look at the Apache directive documentation.

Proper image replacement method

This method displays a specified image on the hotlinker’s page no matter what image they linked to. You can have a simple image which says “do not hotlink!” or you can use your imagination and really discourage them! Read further to find out the best way to create these files.

RewriteEngine on 
RewriteCond %{HTTP_REFERER} . 
RewriteCond %{HTTP_REFERER} !^http://(www\\.)?yoursite\\.com [NC] 
RewriteRule \\.(gif|jpe?g)$ /images/hotlink.$1 [L]

Breakdown of the code

RewriteEngine on

This turns on the mod_rewrite engine in Apache. A requirement for the rewrite commands.

RewriteCond %{HTTP_REFERER} .

This line allows blank referrers. The period in .htaccess means ‘any character’. This means users can manually type in a link to one of your images in their browser, but this is generally not even a problem. If you leave this line out a large percentage of visitors will not see your images. This includes many users behind corporate and ISP firewalls, all AOL users, and many others. Leaving this line in is highly recommended! If a visitor thinks your site is broken, they will most likely not return. If you have any kind of e-commerce site, they probably won’t be doing business with you!

RewriteCond %{HTTP_REFERER} !^http://(www\\.)?yoursite\\.com [NC]

Here the server checks to see if the request is coming from your own domain. Just change the text to match your website. It handles hotlink prevention whether or not the ‘www’ prefix is used. The [NC] flag at the end means ‘No Case’, so it will handle everything.

Notice that there is a backslash before the periods in the domain name. As stated above, in the .htaccess file a period means ‘any character’. Preceeding it with a backslash turns it into a literal period, meaning that there must actually be a period there. When writing .htaccess code it is always best to take all possibilities into consideration.

If you have another site that needs to hotlink from this one, simply duplicate this line and type in the new domain.

RewriteRule \\.(gif|jpe?g)$ /images/hotlink.$1 [L]

This last line blocks all requests for gif, jpg, and jpeg files unless they are from an allowed resource. You will notice the hotlink.$1 file. This code will cause the server to return the proper type of file – which is the format that was requested. A lot of hotlink protection code simply sends one type of file no matter what, but many browsers will not handle this properly, and the above method provides the most flexibility while doing things correctly.

This means that for this example we need to create a hotlink.gif, hotlink.jpg, and hotlink.jpeg. Just create your replacement image, and export it to each of the needed file types. Then just upload them to your server in the location specified by the code (in this case – /images/). You can make the replacement images as large or as small as you want, just keep in mind that if they are too large, you may end up loosing more bandwidth than you would have without protection code!

Proper ‘403 Forbidden’ method

This method is my favorite because it is the easiest on the server and no bandwidth is used at all. Once again, there are several methods to just return ‘nothing’ but generating a ‘403 Forbidden’ error for the hotlinker is perhaps the best. It will not cause any errors or confusion on your server, and the hotlinker will be left with a broken image link.

RewriteEngine on
RewriteCond %{HTTP_REFERER} .
RewriteCond %{HTTP_REFERER} !^http://(www\\.)?yoursite\\.com [NC]
RewriteRule \\.(gif|jpe?g)$ - [NC,F]

Breakdown of the code

The last line is the only difference in these two examples, and this one just contains a dash where the image file would be. Since we are just bouncing back a ‘403 Forbidden’ error message to the hotlinker we do not have to worry about creating any image files.

As mentioned before, if the hotlinkers have simple links to your images (as opposed to images displayed with the <img> tags), clicking on the links will return a ‘403 Forbidden’ error with this method. This is what we want, but there is no reason you cannot create custom error pages which give the user information about your site and links to the main sections. This gives you a much better chance of keeping these visitors!

Changing the blocked extensions

For other extensions to be blocked, you just have to add them between the parenthesis, placing a | (pipe) character between each one. In the case of the jpg and jpeg files, there is only one entry, but the question mark after the ‘e’ means it is optional, so it handles both.

Troubleshooting

The most important thing to remember when testing hotlink protection code is that you must always clear your browser’s cache before each test, or you may just be pulling up cached copies of the test images.

Another important thing to mention is that in many server configurations, mod_rewrite requires that either the FollowSymlinks or SymLinksIfOwnerMatch option is enabled. If your server requires this and you do not have it, you will get a ‘403 Forbidden’ response for all requests. It should be easy to notice in your log files. If you do need it, simply add this line before your hotlink prevention code:

Options +FollowSymLinks

Allow selective hotlinking

There are a couple of different ways to do this. You can of course add the domain name that you want to allow into your .htaccess file as mentioned above, but what about when you have certain images you want anyone to use? Here is the solution I prefer.

Create a directory on your server called ’share’ and create a new .htaccess file inside it, containing this code:

RewriteEngine off

This will counter-act the global .htaccess file, and allow hotlinking from this directory. Now you can keep your bandwidth protected while still letting certain files be hotlinked!

Pages: « 3 [2] 1 » Show All

  1. I check your samples for my site of “juegos gratis in spanish. I run good and fix hotlinking :) thanks.

  2. In terms of the question about images being cached, the way I found to deal with this is to add a bogus query string with a random number as part of the IMG tag for images that need to be dynamic:

    SRC = "name_of_image.jpg?43234324"

    If this number changes, then the old image won’t be pulled from cache. For my cgi generated pages this is easy enough. For my more-or-less static pages, I changed them to shtml, and then do an include on a text file that is nothing but an hourly changed random number. I imagine that other ways of working would have methods to do the same.

    One slight problem that was driving me crazy yesterday: Browsers that allow you to configure them such that they send no HTTP_REFERER variable will always bypass hotlinking protection.

  3. In response to glitter’s comment about protecting flash files, check out my site. There is a free script you can use. And yes the way to do it is with php an .htaccess.

  4. It will be nice to know how to protect flash files, I have seen sites that use .php and protect their flash files, this site over here have a cool way of protecting their files: juegosdiarios.com

  5. 26
    Leon

    A bit late in the day but the info may help others using this method.

    I believe you can also put it inside the WP rule as in:

    # BEGIN WordPress

    RewriteEngine On
    RewriteBase /
    RewriteCond %{HTTP_REFERER} !^$
    RewriteCond %{HTTP_REFERER} !^http://(www\\.)?yoursite\\.com [NC]
    RewriteRule .*.(gif|jpe?g|png|bmp)$ [F,NC]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]

    # END WordPress

    but I’ve not used this method, and as a suggestion to others I wouldn’t use ‘http’ urls inside the htaccess file for directing to an ‘hotlinking’ image, use the path method as used by author ‘/images/hotlink.$1′

    @ Marc (20)

    Unfortunately it will display from their cache but try changing the name of the image.

    @ Jogos (24)

    I think you only need to add ’swf’ to the ‘RewriteRule’ and not the path to the file(s):
    ie: RewriteRule \\.(gif|jpe?g|swf)$

    @ nasir (22)

    Maybe specify ‘jpg’ in the Rewrite Rule and have your thumbs as ‘jpeg’ ?

    @ Manuel (13)

    Yes it does break images for RSS feeds but there are workarounds depending on your platform.

    ie: In Wordpress there is a hotlinking plugin that stores the RSS images in a different folder and uses them for the feeds.

    and I’ve seen an htaccess RewriteRule somewhere that works but you have to specify each feed separately, you’ll have to do a search as I can’t remember where it was, but it is possible.

  6. Gr8 article. I was having a tough time setting up hotlinking on my site with wordpress blog setup on it. Even the my hosting service guys were unable to solve it. then i googled it and found the solution.

    If i keep hotlinking code before wordpress code. then it works.

    Thanks again

  7. I want to block my SWF file (flash files). I tried this code and it did not work.

    RewriteEngine on
    RewriteCond %{HTTP_REFERER} .
    RewriteCond %{HTTP_REFERER} !^http://(www\\.)?MYDOMAIN\\.com [NC]
    RewriteRule \\.(swf)$ /games/arquivo/hotlink.swf [L]

    Why is not working ?

  8. I have a question: on my mandrake linux server, i have several virtual hosts, and hotlinking works only for those directories that are server from under MAIN document root; however, for images stored under /home/$userdir , it does not work even if i put a .htaccess file there, too ! Any suggestion ?

  9. i have hotlink protection on my website it works great, but i want to modify it such that it does not block only the files which start with ‘thumb_’ and block the rest of files can some one help me with this.

    this is the possible line that i have coded but does not work.

    RewriteRule !.*/thumb_\.(jpg|jpeg|gif)$ http://www.hqcelebphotos.com/error.png [NC,R,L]

  10. This article came in handy for my sites. Appreciate it! Helped a lot. keep up the good work!

  11. 20
    Marc

    Hey Admin,

    Great article. Made sure to bookmark you on my new del.icio.us account :)

    I got my htaccess file working and it’s stopping the hotlinking. Unfortunately when they visit the offender’s page, my replacement image gets cached in their hard drives. When they visit my site after reading (IMAGE AVAILABLE AT XYZ.COM), the images from my site are loaded from their cache instead of from my site, using the accepted referrer. Any way around this? I don’t want to institute something like “nocache” on my site (even if it would help) because it would eat up a lot of bandwidth I’m trying to conserve.

    Haha long little comment but maybe you or someone else might have some thoughts!

    Cheers,

    Marc

  12. 19
    Troll

    I think it’s important to mention IIS Mod-Rewrite Pro:

    http://www.micronovae.com/ModRewrite/ModRewrite.html

    It is fully compatible with apache mod_rewrite and also supports .htaccess!

  13. I forgot to write… On my site you are free to browse with that, but when somebody (even google) link me, then it shows that 403…

  14. Ryan: Personally, I put my hotlink code before the WordPress code in the .htaccess.

  15. 16
    Ryan

    I’ve got a question specifically about htaccess and Wordpress. Where do I place the hotlink protection code in the file? Before or after the Wordpress portion? It’s currently after the Wordpress code and before SEO ReWrite. Thanks!

Pages: « 3 [2] 1 » Show All

Leave a Comment

Before you comment: If you are having an issue with a script, please make sure you have read the entire article. Also, please read through the comments because most common issues have already been discussed many times. Thanks.


Be sure to wrap all code in <code></code> tags.