[Home]Prevent bandwidth theft

HomePage | RecentChanges | Preferences | Newbie Help

Preventing bandwidth theft (hot linking)

Hot linking can be prevented by having the server examine the referrer http header, and redirect requests for images to another location if the referrer is from a site other then your own.

Under Apache this can be achieved with mod_rewrite. The directives go in the usual places, e.g. .htaccess

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?your_domain.com/.*$ [NC]
RewriteRule \.(gif|jpg|jpeg|png)$ http://www.your_domain.com/bad.gif [R,L]

Note that this allows requests for the image when no referrer is specified, it is acceptable (according to http) to not send a referrer header, so a blank referrer is allowed as well a one from your own site.

In this case, bad.png is returned instead of whatever image the user requested. You should create the image with a suitable message.

You can add additional file extensions to the last line of the rule.

It should be noted that a number of software packages which are labeled "firewalls", but are really rather more then that, rewrite the referrer header to something invalid, e.g. claiming to come from the URI "Protected by Norton Firewall" (yes - it isn't a URI, its invalid, spamming, privacy freakish garbage). Visitors using these software packages will find themselves seeing bad.png for all the images. To deal with this, you might keep an eye on your server logs and ban certain domains explicitly, or to add a rule that only blocks http or nttp URIs that are not your own.

RewriteEngine on
RewriteCond %{HTTP_REFERER} ^[http|nttp].*$
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?your_domain.com/.*$ [NC]
RewriteRule \.(gif|jpg|jpeg|png)$ http://www.your_domain.com/bad.gif [R,L]

Further reading:

PHP Solution: http://www.phpdeveloper.org/view_tut.php?id=52

ASP Solution:

In ASP, the "hard" part is serving the image, once you've determined it's a request you want to honor (by examining Request.ServerVariables("HTTP_REFERER") and perhaps Request.ServerVariables("HTTP_USER_AGENT") as well).

Once you've decided to serve the image, you do so by first sending a content-type header, and then the image file itself, as a stream.

For example:

 'Assume sImage is the name of the image you want to serve:
 'e.g., 'images/bubba.jpg'.

 Dim sContentType  'Content-type of the image
 Dim sImageFile    'Full path and file name of the image file

 'Call your function for figuring out the content type.
 'For 'bubba.jpg', you probably want to use 'image/jpeg'.

 sContentType = GetContentTypeForImage(sImage)

 'Call your function for figuring out the absolute
 'path to the image on your server. Might just be:

 sImageFile = Server.MapPath(sImage)

 'Get ready to serve. The content-type *must* be the first
 'thing you send to the user agent.

 On Error Resume Next

 'Use ADO to open the image file and send it back
 'to the client as a binary stream.
 Set imgStream = Server.CreateObject("ADODB.Stream")

 If ( (Err.Number = 0) ) Then
    'Load up the image file.
    imgStream.Type = adTypeBinary
    imgStream.LoadFromFile sPath

    'Serve up the right content type.
    Response.ContentType = sContentType

    'Serve the image and close the stream.
    Response.BinaryWrite imgStream.Read
    Set imgStream = Nothing
    'You've got a problem this won't help with
 End If

HomePage | RecentChanges | Preferences | Newbie Help
This page is read-only | View other revisions
Last edited August 25, 2003 3:52 am (diff)

This FAQ is happily hosted by Betadome Digital Media