HOW TO: Prevent hotlinking in WordPress, redirect to an attachment page for the image, or send 404 response

hotlinking

What you’ll need

  1. You will need WordPress installed (version isn’t too important, but it’s nice to be up to date)
  2. Your server will need to be Apache and capable of running PHP with mod_rewrite enabled – if you are running WordPress succesfully then you most likely have all of this.
  3. You will need to have FTP access to your server to upload these scripts

The .htaccess file

Here is the .htaccess file that you should place inside of your /wp-content/ folder:

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} .*jpg$|.*gif$|.*png$ [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !yoursitedomain\.com [NC]
RewriteCond %{HTTP_REFERER} !afriendlysitedomain\.com [NC]
RewriteCond %{HTTP_REFERER} !google\. [NC]
RewriteCond %{HTTP_REFERER} !baidu\. [NC]
RewriteCond %{HTTP_REFERER} !search.msn.com\. [NC]
RewriteCond %{HTTP_REFERER} !bing\. [NC]
RewriteCond %{HTTP_REFERER} !search\?q= [NC]

RewriteRule (.*) /view-image/?id=$1

The PHP script to redirect back into WordPress

Here is the full PHP code (remember: all source files are at the bottom of the post!), which should be inside of an index.php file within a folder called /view-image/ in the root of your server.

If you need to adjust this location, say you want to have it inside of a “/blog/” folder, please make sure to update the last line of the .htaccess file to point to the correct location!

<?php
require('../wp-blog-header.php');
$imageURL = strip_tags( $_GET['id'] );

if ($imageURL !== "") {
	$query = "SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' AND post_parent > '0' AND guid = '$imageURL'";
	$linkedImage = $wpdb->get_row($query);
	$attachmentUrl = get_attachment_link($linkedImage->ID);
	if($attachmentUrl !== "" && !is_numeric(stripos($attachmentUrl, "attachment_id=0"))) {
		header("HTTP/1.1 302 Found");
		header("Location: ". $attachmentUrl);
		exit;
	}
}
$newUrl = get_site_url() . "/image-not-found";
header("HTTP/1.0 404 Not Found");
header("Location: " . $newUrl);
exit;
?>

How can I test this?

If you don’t have immediate access to many websites besides your own, or uploading an HTML file to test hotlinks from another domain would take too long, there are easier methods to test this.

If you want to make sure these two scripts are working, try this hotlink checker script – and make sure to clear your cache/refresh the page/try in a new browser.

If you don’t see any image, our script install worked!

Special thanks to A List Apart for their insight and ideas on hotlinking.

That’s it! Again, as promised, here are the source filse for this tutorial:

Download: prevent-hotlinking-wordpress.zip

Related Posts