Prevent Hotlinking, and Internet Explorer 6
Are your images missing in Internet Explorer 6?
It appears that some details of a common method used to prevent hotlinking on Apache servers may cause some issues. We stumbled across this when users reported to us that in Internet Explorer 6 our brand new website was not rendering properly - neither images nor CSS styling were appearing. Yet other users of that browser reported no such trouble.
Eventually we came to realize that our .htaccess hotlinking-prevention code was choking some IE6 browsers.
Hotlink Prevention
No one could possibly mistake me for an Apache guru. Yet sometimes we are forced to dive into waters far too deep to swim confidently. It is with this background hereby declared that I present the following for your consideration.
To prevent another website from displaying our site's assets, i.e. stealing our bandwidth and intellectual property, we had included in our .htaccess file code based on that suggested by numerous websites:
<IfModule mod_rewrite.c>RewriteEngine OnRewriteCond %{HTTP_REFERER} !^$RewriteCond %{HTTP_REFERER} !^http://(www\.)?yourdomain.com/.*$ [NC]RewriteRule \.(gif|jpe?g|js|css)$ - [F]</IfModule>
Our focus here is on line 4:
RewriteCond %{HTTP_REFERER} !^http://(www\.)?yourdomain.com/.*$ [NC]
It became clear that the regex pattern in that line was causing IE6 trouble under some circumstances (so far all problems reported were with 6.0.2900 xpsp sp2 gdr).
Several aspects of that regex pattern seem to be problematic, the critical one being it requires that a slash (/) appear after .com. (Although it properly makes the existence of characters after .com/ optional)
So, given the common use of this pattern which requires a slash to follow .com, how is it that when we enter www.yourwebsite.com, without a trailing slash, the page typically renders properly anyway? Well it turns out that Apache sends a redirect to the client to tell it to add the trailing slash.
It also turns out there are some occasions when all browsers will fail to add the slash, for example after a series of complex rewrite rules. But under typical circumstances, the Apache/browser team handles this task quite reliably. Except, that is, for some versions of IE6, [at least under some circumstances]. And when IE6 fails to add the trailing slash, the regex pattern declared the asset files to be off-limits.
So, IE6 is failing to add that slash, but it is our .htaccess code that is wreaking the havoc.
Other problematic patterns:
We have found other published patterns that seem to us to have other issues:
For example:
!yourdomain\.com
An evil-doer could easily purchase urls to circumvent this pattern:
http://yourdomain.comfrey.net (and thus http://yourdomain.comfrey.net/subdir/page.php)
or
mine-and-yourdomain.com (and thus mine-and-yourdomain.com/subdir/page.php)
And this one:
!^http://(www\.)?yourdomain.com(/)?.*$
is circumvented by:
http://yourdomain.comfrey.net (and thus http://yourdomain.comfrey.net/subdir/page.php)
These sort of situations would be uncommon to be sure, but while we are choosing our regex pattern, we opted to handle them as well.
Our regex pattern to prevent image hotlinking
This is currently our preferred pattern:
!^http://(www\.)?yourdomain.com(/.*)*$
which:
- does not require a slash to immediately follow
.com(and thereby works happily in all reported versions of IE6) - does preclude any character other than a slash from immediately following the
.com - does prevent any characters other than
http:// (+/- www.)from precedingyourdomain
(The unescaped period between divahtml and com means "any character" when really we intend that it mean "a period", but in fact only with a period can a url match the entire pattern.)
Our current .htaccess code to prevent hotlinking:
Putting it all together, with a filip (download this prevent-hotlinking code as a text file):
<IfModule mod_rewrite.c>RewriteEngine OnRewriteCond %{HTTP_REFERER} !^$RewriteCond %{HTTP_REFERER} !^http://(www\.)?yourdomain.com(/.*)*$ [NC]RewriteCond %{HTTP_REFERER} !google\. [NC]RewriteCond %{HTTP_REFERER} !search\?q=cache [NC]RewriteRule \.(gif|jpe?g|js|css)$ - [F]</IfModule>
(Line 3 allows for those cases when no referrer is available. Lines 5 and 6 allow google and cached items, respectively, to link to our images. Fyi [NC]=NoCase and [F]=Forbidden)
This solution does seem to work for us. Our users are happy, and so are we, notwithstanding the fact that we found ourselves in these very deep waters before we knew it.
One final note: we use a hosted shared server. It is possible that it is mis-configured in such a way as to play a role in the Internet Explorer 6 issue reported here. How this might impact only one version of one browser eludes me, but then, as I said before, i am just treading water when it comes to Apache. However, if our host did in fact make such a mistake, presumably others might as well, and therefore our regex pattern might have more general utility, and, importantly, can do no harm otherwise.
Feedback
"Thanks for your fix. My site got all screwed in Internet Explorer 6, but now it works :) Thanks a lot!" - Arun Kale, 8/2/2007
More feedback is always welcome.
- E. Michael Brandt
7/16/2007
Other resources:
Unobtrusive Scripts and Dreamweaver Extensions