Forum Moderators: phranque

Message Too Old, No Replies

Mod_rewrite to prevent hotlinking

         

premasagar

11:55 am on Apr 8, 2004 (gmt 0)

10+ Year Member



To prevent hotlinking from another site to images on my site, I put a rule in .htaccess that will display a replacement image (basically saying that this image has been stolen...) if the HTML Referer is set and is not from my site.

This is based on code I found at [webspiffy.com ].

I thought I had it working, but it now seems to allow all images to be displayed anyway...


Options FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_URI}!.*images/stolen\.gif$
RewriteCond %{HTTP_REFERER}!^$
RewriteCond %{HTTP_REFERER}!^http://(www\.)?mysite\.com.*$ [NC]
RewriteRule images/.*$ [www\.mysite\.com...] [R,L]

Any thoughts appreciated,
:o) Prem

dcrombie

3:01 pm on Apr 8, 2004 (gmt 0)



I'm not sure of the exact problem, but you can simplify your rules a bit which might be a move in the right direction:

RewriteCond %{REQUEST_URI} !images/stolen\.gif$ 
RewriteCond %{HTTP_REFERER} .
RewriteCond %{HTTP_REFERER} !^http://(www\.)?example\.com/? [NC]
RewriteRule images/ [www\.example\.com...] [R,L]

jdMorgan

4:12 pm on Apr 8, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



... or use an internal rewrite to hide the fact that you're replacing the image (makes it look like scary magic) ;)

RewriteCond %{REQUEST_URI} !^/images/stolen\.gif$
RewriteCond %{HTTP_REFERER} .
RewriteCond %{HTTP_REFERER} !^http://(www\.)?example\.com [NC]
RewriteRule ^images/ [b]/images/stolen\.gif [L][/b]

When testing mod_rewrite code, be sure to flush your browser cache after any change is made to the mod_rewrite code on the server. Otherwise, your browser will probably serve you a cached result, which will not reflect the changes made to the code on the server.

Jim

premasagar

12:28 am on Apr 9, 2004 (gmt 0)

10+ Year Member



The process seems to be working. Thanks a lot.

But one slight issue - if I first go to an external site that hot-links the image, and I see the "stolen.gif", and if I then go to the actual site and view the relevant page, the stolen.gif image actually appears on the page until I refresh. Then the proper image appears. (Browsers: IE6 & Opera 7)

I have the http headers set not to cache the page.

Any ideas how to prevent this?

Prem.

jdMorgan

8:01 am on Apr 9, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Prem,

If this is really a concern, in that you think a "real" visitor might actually do this, then mark stolen.gif as non-cacheable using Apache mod_expires and mod_headers:


<FilesMatch "stolen\.gif$">
ExpiresDefault A1
Header unset Cache-Control:
Header append Cache-Control: "no-cache, must-revalidate"
</FilesMatch>

Jim

premasagar

10:45 am on Apr 9, 2004 (gmt 0)

10+ Year Member



Great. Thanks Jim. I appreciate your help.

You sound a little cautious about preventing caching on this image. Is it a bad idea for any reason?

Prem.

jdMorgan

12:55 am on Apr 10, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



No, but caching is a complex subject, and many folks just don't want to mess with it. I implement full cache-control on all my sites, but it's a good idea to do it in an informed manner.

(And besides, I'm always cautious -- I am not an expert in all things, and others' opinions may reasonably be expected to be different from my own.)

Jim

Dunkelkind

5:05 pm on Apr 21, 2004 (gmt 0)

10+ Year Member



Hi,
I was going to implement this on my own domain, but for some odd reason it doesn't work.

Do the given examples assume that all pictures are stored to ./images/ folder?
My images are in a different folder named /gallery/data/media/ and there are quite some subfolders containing images generated by an interactive user gallery.

Here's the was I've set up the .htaccess section in the www root folder :

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

I created a subfolder in www root containing a stolen gif. Btw, there will be only jpg files in my gallery so do I have to edit the htacces Rewrite rule like this?

RewriteRule \.(gif¦jpg)$ /images/stolen\.gif [L]

I'm quite a greenhorn in working with the RewriteEngine and tried some 'working' solutions (without success till now ...).

Any help is gladly appreciated :-)

jdMorgan

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

WebmasterWorld Senior Member 10+ Year Member



Dunkelkind,

Welcome to WebmasterWorld [webmasterworld.com]!

> do I have to edit the htacces Rewrite rule like this?
> RewriteRule \.(gif¦jpg)$ /images/stolen\.gif [L]

Yes, that should work much better, since your images are in many different directories, but note the following (minor) correction:

 RewriteRule \.(gif¦jpg)$ /images/stole[b]n.g[/b]if [L] 

Also, note that the "¦" character must be a solid vertical pipe character for use in mod_rewrite patterns; posting them in this forum changes them to broken vertical pipes.

Finally, let me highlight something that I missed at the beginning of this thread: It is more usual (and far safer) to use

Options +FollowSymLinks
(Note the "plus sign"). This enables FollowSymLinks (and mod_rewrite), but it does not change any other server options settings. If you use Options without "+" or "-", then all other options are affected in the current directory and in all directories below the current directory, unless specifically overridden in those subdirectories. This is OK if this is what you want and expect, but can be a disaster otherwise.

Here's another hotlinking thread [webmasterworld.com] running right now that might give you some more perspective on your project, and I just posted this mini-tutorial [webmasterworld.com], which--although addressed to a different problem--may give you some more background as well.

Jim

Dunkelkind

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

10+ Year Member



Jim,
many thanks for that quick answer. I will edit my .htaccess and will see what happens ;-)

Since my webhosting company assured that they enabled full mod_rewrite support, I think the best solution is to use this mod including the internal redirection.

premasagar

7:03 pm on Apr 23, 2004 (gmt 0)

10+ Year Member



Hi there,
I have added to the code I was using to prevent caching of the "stolen.gif" image. I also wanted to prevent caching of images from a certain folder ("images/b/"). This works, but I notice that when one of those matched images appears on a page, ALL of the images on the page are prevented from being cached, which is not what I had intended.

Any ideas? Here's the code:


<FilesMatch "(stolen\.gif$¦images/b/.*\.(gif¦jpe?g¦png)$)">
ExpiresDefault A1
Header unset Cache-Control:
Header append Cache-Control: "no-cache, must-revalidate"
</FilesMatch>

Thanks, Prem

jdMorgan

8:01 pm on Apr 23, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Yes, FilesMatch works with filenames, not directory names, so that may be causing the trouble. Put the code in an .htaccess file *in* the directory you want it to affect, if you only want it to affect files in that directory.

Remember that each and every page, script, external stylesheet, and image is fetched with a separate HTTP request; Each requested element will be returned with its own cache-control headers, so they cannot "interere with each other" on the client end - he problem has to be on the server.

Jim

premasagar

11:09 am on Apr 25, 2004 (gmt 0)

10+ Year Member



Thanks for your suggestion, Jim. Good idea.

The cache-control certainly seems to be taking effect. I notice that if I right-click to save one of the images, the browser wants to save it as "untitled.bmp". However, the orginal image (say, a .jpg or .gif) IS actually saved in the browser's cache. This happens in both Opera 7 and IE 6.

Any ideas how to actually stop the images being saved to the browser's cache?

Thanks in advance,
Prem.

jdMorgan

6:28 pm on Apr 26, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You could send a 'name="pragma" content="no-cache"' header, but that won't stop the browser from keeping a copy in its temporary memory, from which it can be saved. If something can be displayed by a browser, it can be saved by a browser; If you don't want soemthing copied, don't publish it on the Web.

Jim

premasagar

1:40 am on Apr 27, 2004 (gmt 0)

10+ Year Member



If you don't want something copied, don't publish it on the Web.

Yes, the old web proverb is correct.
Thanks, Prem.

CNibbana

4:10 am on May 27, 2004 (gmt 0)

10+ Year Member



I have employed this solution and it works great. Is there a way to modify the rewrite such that 'www' or any subdomain.domain.com will not be blocked without having to physically list every subdomain?

I have tried the following and about 20 other variations and can't get it to work:

RewriteCond %{HTTP_REFERER} .
RewriteCond %{HTTP_REFERER}!^http://[^(.*)\.]?domain\.com [NC]
RewriteRule \.(gif¦jpe?g¦png)$ - [NC,F]

jdMorgan

4:28 am on May 27, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Did you try this?

RewriteCond %{HTTP_REFERER} .
RewriteCond %{HTTP_REFERER} !^http://(.+\.)?domain\.com [NC]
RewriteRule \.(gif¦jpe?g¦png)$ - [NC,F]

Ref: [etext.lib.virginia.edu...]

Jim

CNibbana

2:02 am on May 28, 2004 (gmt 0)

10+ Year Member



That worked great Jim, thanks!