howto: preventing hotlinking

I've had a nifty anti-leeching/hotlinking solution on my blog for a while, and I've now moved it over to work with my zenphoto installation. I thought I'd share it with those here who might be interested.

This solution has a couple nice features. If the hotlink is a page somewhere else that is just loading your images, it'll just get a broken image. If the hotlink is actually a link directly to the image, a simple page loads -- but since the file to image display page mapping is easy in zp, I've added in some javascript that just forwards to the image page. It also won't break Google Image Search.

The small HTML is much smaller than just about any image file, so you save on bandwidth. You break images for jerks just stealing your images, and you still provide a navigable page for those who follow links to your stuff. Most of the time when people hotlink to your image, the image is in their browser's cache, so they won't realise their html is showing broken images.

You need to do two main things. First is to modify your .htaccess file. My zp installation is in `/gallery`, so change all references to match your directory:

`

RewriteEngine On

RewriteBase /gallery

#hotlinked image protection

RewriteCond %{REQUEST_FILENAME} .(gif|jpe?g|png)$ [NC]

RewriteCond %{HTTP_REFERER} !^$

RewriteCond %{HTTP_REFERER} !alexwilsonphoto.com [NC]

RewriteCond %{HTTP_REFERER} !google. [NC]

RewriteCond %{HTTP_REFERER} !search?q=cache [NC]

RewriteRule (.*) /gallery/showpic.php?pic=/gallery/$1 [R,NC,L]



`

You'll also need to change the `alexwilsonphoto.com` to match your domain, obviously.

So, that will snag any non-empty referrer that isn't your domain and isn't Google and redirect it to showpic.php.

Next, add this as showpic.php into your zp install dir:

`

<?php<br />
header("Content-type: text/html");

header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");

header("Cache-Control: no-store, no-cache");

header("Cache-Control: post-check=0, pre-check=0", false);

header("Pragma: no-cache");

$pic = strip_tags( $_GET['pic'] );

if ( ! $pic ) {

die("No picture specified.");

}

?>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"<br />
"http://www.w3.org/TR/html4/strict.dtd">





<?php echo($pic); ?>


http-equiv="Content-Type"

content="text/html; charset=iso-8859-1"

>



<?php if (substr($pic,0,14)=="/gallery/cache"){ ?>



<?php }else{ ?>

.php');">

<?php } ?>

Image from http://alexwilsonphoto.com/

image" alt="Image">

Please do not hotlink to images or use without permission. Please visit http://alexwilsonphoto.com/ for more of my photography.





`

That code will need some tweaking. In addition to changing the domain and /gallery references, you probably need to change the 14 in`substr($pic,0,14)=="/gallery/cache"` if your install directory name is longer or shorter than "gallery".

That line of code, BTW, looks for references to the cache directory -- if the link is to something in the cache directory, it will display the page with the image. If the link is to the non-cache version of the image file, it will forward the browser to the theme's image display page, which is much snazzier.

Note that in my own setup I'm displaying the non-cache version of the image as what is always shown in the theme's image display page -- this might need some more fixing to work with the default zp setup, or with a bit more smarts it could strip out any of custom sizing stuff added to the name and then always forward to the image page. Hopefully this is a good starting point, at least.

The coolness does come with a price -- you won't be able to hotlink yourself, which could be a problem depending if you email image links to friends, or want your images showing in RSS or something.
Sign In or Register to comment.