HOWTO: Prevent Hot-linking of Your Images Using Apache's mod_rewrite Engine

| 2 TrackBacks
bandwidthzn9.jpgHot-linking (a.k.a., inline linking) of images and other resources is a common problem for system and network administrators across the web.  In a nutshell, hot-linking involves folks using your site/blog as the hosting mechanism for images and other resources on their sites or forums.  Wikipedia has a nice write up on hot-linking.  For example, when a user posts a message on a forum that includes an <img> tag sourcing an image hosted on kolich.com:

<img src="http://mark.koli.ch/american-flag.png" />

This is irritating to system and network administrators because it wastes bandwidth and unnecessarily consumes server resources.  Unless you're running a dedicated static content server, why would you want to use your web-server and network bandwidth to host images for forums or other blogs?  In most cases, you don't.

Luckily, Apache's mod_rewrite module makes it easy to stop hot-linking by blocking requests for images and other content that don't originate from your domain.  Here's my Apache configuration (in httpd.conf) that stops the hot-linking of my images.  Note, you can also put this in an .htaccess file assuming your hosting provider gives you permission to do so:

## Prevents hot-linking of my images on other sites.
## Will send back a 49x49 transparent pixel in place
## of hot linked images sourced from other sites.
RewriteCond %{HTTP_REFERER} !^http://(.+\.)?kolich\.(com|mobi)/ [NC]
RewriteCond %{HTTP_REFERER} !.*twitter\.com/ [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteRule .*\.(jpe?g|gif|bmp|png)$ /pixel.gif [L]

Using RewriteCond, I can check the HTTP referrer header to ensure that the request for an image originated from a user visiting my blog (under *.kolich.[com,mobi]).  I also allow requests originating from *.twitter.com given that I often post images and other stuff to my Twitter feed.  If the request for an image did not originate from *.kolich.[com,mobi] (e.g, on a forum or another blog) I simply send back a 1x1 transparent pixel (49-bytes) instead of the image itself.

Here's a request in my log files showing that someone tried to hot-link to my "case of the monday's" image in this forum thread.  Note that I'm sending back the 1x1 transparent pixel (49-bytes) instead of the actual JPG image the user tried to source:

173.34.220.243 - - [11/Jul/2009:11:40:18 -0700]
"GET /2009/01/05/case-of-the-mondays.jpg HTTP/1.1" 200 49
"http://forums.vwvortex.com/zerothread?id=2130343&page=63"
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; GTB5)"

Enjoy.

Did You Find this Helpful?

Did you find this post helpful, or at least, interesting?

  

Send Mark a Direct Message

If you'd like to send me a direct message, please do so below. However, I do not publicly post comments or messages submitted directly to me. So, if you're going to try to SPAM me, or my blog, you're pretty much wasting your time.

400 characters remaining

Error

About Mark

A Silicon Valley native, Mark Kolich is a full-time Software Engineer, a casual entrepreneur, and a consultant for hire. A web technologies expert, his current focus is on building powerful and robust cloud-driven web-applications using Java, PHP, Perl, AJAX, DHTML, CSS, and JavaScript. His favorite programming languages are PHP, Java and JavaScript. He uses Linux, enjoys biking to work, loves building great software, and always writes elegant, readable, and maintainable code.

2 TrackBacks

OK, I'm on a slightly vengeful tear this week dealing with the infamous hot-linking problem.  Here, I explained how to more gracefully handle hot-linking blogs, forums, and other sites.  Then yesterday, I explained the situation to a few folk... Read More

Yesterday, I caught kentuckysportsradio.com hot-linking to images on my blog.  I noticed an insane amount of traffic on my server requesting a single image, over and over again from the same referrer.  Classic case of hot-linking, and boy, do... Read More

Twitter (@markkolich)

Translate

About this Entry

This page contains a single entry by Mark Kolich published on July 11, 2009 12:05 PM.

MySQL Trigger: ERROR 1442 (HY000): Cant update table 'tbl' in stored function/trigger because it is already used by statement which invoked this stored function/trigger was the previous entry in this blog.

Gagawa PHP 1.2-beta Released! is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.