November 17th, 2009
I like my shared host, it’s cheap, it’s great, and any problems are easily overcome through a little ingenuity. In this case it’s hotlinking, something that’s been a serious problem in the past without a clear solution. Time has proven blocking outside referers with an .htaccess file is both ineffective, and can cost honest users. Without access to the httpd.conf, I’m forced to do things a little differently.
The system I have works using an .htaccess file that requires all files accessed in its folder have a unique key in the URL (as part of the query, the stuff that comes after the ‘?’ symbol). This key is changed every once in a while, and the .htaccess file is simply rewritten with the new information.
The files are updated by a cron job that runs a bash file that updates all the files. It fails gracefully too, if any file is unwritable everything will be left in a working state, albeit one that doesn’t prevent hotlinking anymore. The .htaccess file also lets the previously used key to still be used as well, so that the URLs don’t expire immediately after a new key is introduced.
Here’s how to get it working.
1. Get the files.
Available here. The files in the protected folder should similarly go into the folder you want protected and “update-key” should go somewhere else where it can be executed by the cron job but have no chance of being visible to the outside world. Make sure the file permissions are kept intact, “.htaccess” and “.htkey” files must all be writable by the cron job and “update-key” must be executable.
2. Set up a cron job.
Add a cron job that executes update-key every so often with whatever method you’re allowed. The “update-key” script changes files in the current directory, so you need to execute it in the same folder as the .ht files. Here’s an example cron job that runs every 8 hours. Change the paths to the right locations.
0 0,8,16 * * * cd $HOME/path/to/protected && $HOME/path/to/update-key
3. Use it in your pages.
To generate the URLs, just dump the contents of “.htkey” Â as your key at the end of the URL. Here’s some examples.
<? echo '<img src="http://www.brokenfunction.com/protected/awesome.jpg?key=' . trim(array_pop(file("/path/to/protected/.htkey"))) . '">' ?>
keyfile = open("/path/to/protected/.htkey", "r")
key = keyfile.readline().strip()
print("<a href='http://www.brokenfunction.com/protected/awesome.jpg?key=%s' />" % key)
If anybody can offer some other examples in the comments I’ll add them here.
This isn’t a perfect solution of course, anybody could check with your site and update their links accordingly whenever the key changes, but it’s good for lightweight protection and a lot more reliable than referer blocking.