Search code examples
apache.htaccessmod-rewritehotlinking

Using htaccess for image protection


I am close to launching a photography website and want to give some protection to my images. I have the following as a result of searching on the web:

#Set FollowSymLinks, in most cases already set on the server
Options +FollowSymLinks
#Enable Indexes
Options +Indexes
#Turn on the Rewrite Engine
RewriteEngine on
#Allow my domain
RewriteCond %{HTTP_REFERER} !^http(s)?://(www.)?mydomain.com [NC]
#Allow another domain
#RewriteCond %{HTTP_REFERER} !^http(s)?://(www.)?anotherdomain.com [NC]
#Allow blank referrers or delete this line to block them
#Deleting this line also blocks access to images by filepaths
RewriteCond %{HTTP_REFERER} !^$
#Allow search engines
RewriteCond %{HTTP_REFERER} !google. [NC]
RewriteCond %{HTTP_REFERER} !search?q=cache [NC]
RewriteCond %{HTTP_REFERER} !msn. [NC]
RewriteCond %{HTTP_REFERER} !yahoo. [NC]
#File types to be blocked
RewriteRule \.(jpg|jpeg|png|gif)$ - [NC,F,L]
#OR
#First allow an image to be hotlinked to avoid looping
#RewriteCond %{REQUEST_URI} !^mydomain.com/image/hotlinker.gif$
#Then display it as a custom image
#RewriteRule .(jpg|jpeg|png|gif)$ mydomain.com/image/hotlinker.gif [NC,R,L]

1) Is there a way to stop an image being called up by entry of its filepath that does not involve blocking blank referrers? I have a few instances where I would like to do this, but not the entire site.

2) Do I have the correct code to allow Google, MSN and Yahoo proper access to my images?

3) The code I have is merged from more than one source. As I have no knowledge of the syntax, I’m wondering why only the first RewriteRule without a substitute image starts with a \ and not the second one?

Appreciate any feedback, thanks.


Solution

  • 1) Is there a way to stop an image being called up by entry of its filepath that does not involve blocking blank referrers? I have a few instances where I would like to do this, but not the entire site.

    I don't think there's a way, but you can list the exceptions in RewriteCond for a separate set of rules:

    # Check to see if referer is blank
    RewriteCond %{HTTP_REFERER} ^$
    # Check to see if it isn't one of the files we're going to allow blank referers
    RewriteCond %{REQUEST_URI} !^/images/allow_blank_referer/
    RewriteCond %{REQUEST_URI} !profile_picture\.png$
    # Block images
    RewriteRule \.(jpg|jpeg|png|gif)$ - [NC,F,L]
    

    That example will block all blank referers, except any requesting images from /images/allow_blank_referer/ and any image that ends with profile_picture.png.

    2) Do I have the correct code to allow Google, MSN and Yahoo proper access to my images?

    No, these lines you have in your .htaccess:

    RewriteCond %{HTTP_REFERER} !google. [NC]
    RewriteCond %{HTTP_REFERER} !search?q=cache [NC]
    RewriteCond %{HTTP_REFERER} !msn. [NC]
    RewriteCond %{HTTP_REFERER} !yahoo. [NC]
    

    Simply allow people who load an image linked from google/msn/yahoo and their search caches. For example, if someone does an image search on google and clicks on one of your images, you won't block them.

    What you'd want to do to ensure google, msn, and yahoo bots won't be blocked is to check the HTTP_USER_AGENT, for example, underneath those rewrite conditions you can insert:

    RewriteCond %{HTTP_USER_AGENT} !googlebot [NC]
    RewriteCond %{HTTP_USER_AGENT} !msnbot [NC]
    RewriteCond ${HTTP_USER_AGENT} !slurp [NC]
    

    Those will bypass referer checks if any of those 3 things are present in the user agent (slurp = Yahoo!), you can get a list of user-agents from places like http://www.robotstxt.org/db.html

    3) The code I have is merged from more than one source. As I have no knowledge of the syntax, I’m wondering why only the first RewriteRule without a substitute image starts with a \ and not the second one?

    The first has a "\" to escape the ".". The "." in a regular expression matches anything, kind of like a wildcard and the "\" escapes it, meaning "I really mean the period and not the wildcard". The commented out RewriteRule is missing "\" probably because someone was being lazy. It will still match a request ending in, for example, .gif, but it will also match something ending in zgif whereas the first RewriteRule would not. If you are going to use the commented out RewriteRule (if you do, make sure to comment out RewriteRule \.(jpg|jpeg|png|gif)$ - [NC,F,L]), I'd suggest putting a "\" in front of that first period.