Forum Moderators: phranque

Message Too Old, No Replies

mod_rewrite and prevent hotlinking

prevent hotlinking with subdomains

         

adb64

8:52 pm on Apr 20, 2004 (gmt 0)

10+ Year Member



I want to prevent hotlinking of any of the images on my site. I have several subdomains so I added the following to my .htaccess file in the root of www.mydomain.com:

RewriteEngine on
RewriteCond %{HTTP_REFERER}!^$
RewriteCond %{HTTP_REFERER}!^http://(.+\.)?mydomain\.com [NC]
RewriteRule \.(gif¦jpg¦png)$ [www\.mydomain\.com...] [R,L]

This will give me 500 Internal Server errors on all of my pages.
The PHP file will generate an appropriate image when one of my images is hotlinked from any other site than one of my own (*.mydomain.com). This image is created from a png image using 'imagecreatefrompng()'. Also on all of my webpages are some images created the same way. But I think that should not be a problem, opening a file in PHP is not handled via .htaccess (I hope!)

Any ideas what might be wrong here?

Thanks,

Arjan

jdMorgan

12:37 am on Apr 21, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Arjan,

Welcome to WebmasterWorld [webmasterworld.com]!

Yes, you need to be aware of some of the quirks of posting on this board...

First, spaces preceding "!" are deleted. But they are required in the code you posted.
Second, solid vertical pipes are converted to broken "¦" vertical pipes, and must be changed back before you can use the code.

Also, be aware that using a 302 redirect -- as specified by the [R] flag on your rewriterule -- requires the cooperation of the client to follow that redirect. Instead of exposing your technique, I'd suggest using an internal redirect.

Here's the code modified to fix the spacing problem and using an internal redirect. I can't fix the broken vertical pipes, so you'll have to do that.


RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(.+\.)?mydomain\.com [NC]
RewriteRule \.(gif¦jpg¦png)$ /hotlink\.php [L]

Jim

adb64

8:17 pm on Apr 21, 2004 (gmt 0)

10+ Year Member



Jim,

I tried your code and it still gave me Internal Server Errors, so I turned to my hosting provider (I'm on a virtual host) and asked them whats wrong. And guess what... They don't support mod_rewrite on their systems. Don't ask me why.

Well, thanks for the help anyway,

Arjan

jdMorgan

12:01 am on Apr 22, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Arjan,

Well, I needed to write this up anyway, so here's another simple solution [webmasterworld.com] you may be able to use.

Jim

Dunkelkind

8:56 am on Apr 22, 2004 (gmt 0)

10+ Year Member



Hi,
I'm running into the same issue like Arjan by getting a internal server error. My provider assures, that mod_rewrite is fully implemented.

I tried this with an more easier redirect directive which works fine :

#rewriteEngine on
#rewriteBase /
#rewriteRule ^bla.htm blabla.php

But trying the redirection for hotlinking images to a substitute image I'm running out of luck :-(

I adapted my .htaccess (thanks to all users who already helped me ....) according to this:


+Options FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_URI}!^/images/stolen\.gif$
RewriteCond %{HTTP_REFERER} .
RewriteCond %{HTTP_REFERER}!^http://(.+\.)?mydomain\.com [NC]
RewriteRule \.(gif¦jpg)$ /images/stolen.gif [L]

Between "gif" and "jpg" in the last line I use a solid pipe. I think I must did some typo which cuases the trouble. Unfortunately my provider only provides the Apache access log and not the error log, so I cannot break it down to the line which causes the error. Can someone give me a hint, where the error could be?

adb64

7:50 pm on Apr 22, 2004 (gmt 0)

10+ Year Member



Jim,

Thanks, your proposal works with only a small modification:


<FilesMatch "\.(gif¦jpg¦png)$">
SetEnvIfNoCase Referer ^$ allow_image
SetEnvIfNoCase Referer ^http://(.+\.)?mydomain\.com allow_image
Order Deny,Allow
Deny from all
Allow from env=allow_image
</FilesMatch>

The one thing I had to change was the addition of the env= after the Allow directive.

My next challenge is to show a replacement image, I'm thinking of catching the 403 error with a 403 ErrorDocument and try to find out somehow whether the error was caused by hotlinking and then redirect to my 'stolen image'.

Thanks again,

Arjan

adb64

9:41 pm on Apr 22, 2004 (gmt 0)

10+ Year Member



Ok, well here it is, my 'poor mans' mod_rewrite:

Add the following lines to the .htaccess file:


ErrorDocument 403 /error403.php
<FilesMatch "\.(gif¦jpg¦png)$">
SetEnvIfNoCase Referer ^$ allow_image
SetEnvIfNoCase Referer ^http://(.+\.)?mydomain\.com allow_image
Order Deny,Allow
Deny from all
Allow from env=allow_image
</FilesMatch>

And have the following code in the error403.php file


<?php
$Referrer = getenv("HTTP_REFERER");
if (!eregi("^http://(.+\.)?mydomain\.com",$Referrer))
{
$im = imagecreatefrompng("<mydomain-root>/hotlink.png");
header("Content-type: image/png");
imagepng($im);
imagedestroy($im);
exit();
}
else
{
// 'Normal' text output for the 403 error
}
?>

The image must be send directly from the error document, using a redirection to the image kept me in a loop with my browser complaining about too many redirections.

Hope this may help others with the same problem.

Arjan

jdMorgan

1:03 am on Apr 23, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



> kept me in a loop...

You could add this to the existing SetEnvIfs to prevent a loop:


SetEnvIfNoCase Request_URI ^/hotlink\.png$ allow_image

Jim

Dunkelkind

10:06 am on Apr 23, 2004 (gmt 0)

10+ Year Member



Hi Arjan & Jim,
I tried both scripts (my one with mod_rewrite and the "poor man" version). The mod_Rewrite script causes the 500 error (according to my hosting provider mod_rewrite is enabled so I still believe that there's a syntax error within my .htaccess) and the other one still allows hotlinking my files like before :-(

Testing hotlinking I inserted a PHP directive showing the HTTP referer on one of my sites where the link was finally leading to. The I linked this site from another domain and visited it via the link. Funny thing was, that I got a blank referer (which is nothing obvious as I learned).

So could it be possible that the "poor man" script doesn't work when hotlinking without sending the HTTP referer (blank) occurs?

Any help is gladly appreciated :)

adb64

10:59 am on Apr 23, 2004 (gmt 0)

10+ Year Member



Hello Dunkelkind,

This is true, when a blank referrer is received the image will still be shown. This is required as sending the referer can be disabled which would mean that such visitors can't see the images on your own site either. This is accomplished by the line:


SetEnvIfNoCase Referer ^$ allow_image

Removing this line from .htaccess will indeed also deny visitors with a blank referer from viewing the images, but also those on your site!

I put a test page on a site of my employer with a hotlink to an image on my site for testing, click the link below if you want to see the 'poor mans' version at work.

http://example.com/~arjaboer/hotlink.html

Arjan

[edited by: jdMorgan at 2:41 pm (utc) on April 23, 2004]
[edit reason] No URLs, please. See TOS. [/edit]

Dunkelkind

11:23 am on Apr 23, 2004 (gmt 0)

10+ Year Member



Hi Arjan,
am I supposed to see the crocodiles?
I get no 403 page or an image generate by the 403.php unless it is the one wit the crocs. ;)

Dunkelkind

adb64

12:56 pm on Apr 23, 2004 (gmt 0)

10+ Year Member



Hi Dunkelkind,

When the hotlink detection works you should see a warning image. When the detection fails for some reason you will indeed see a pair of crocodiles, which is the case when you send a blank referrer.
I can't see that as I have no access to my employers log files. The only thing I see in my own 403 logging is that on 2004-04-23 13:25:39 CET someone from IP 82.***.116.152 accessed that page, probably you. In that case you should have seen my warning image, which certainly has no resemblance with a crocodile.

Regards,

Arjan

[edited by: jdMorgan at 2:43 pm (utc) on April 23, 2004]
[edit reason] Obscured specifics [/edit]