Forum Moderators: phranque

Message Too Old, No Replies

Blocking Hotlinking Help

Help with blocking .zip and graphic hotlinking.

         

RockyB

9:47 pm on Jun 12, 2005 (gmt 0)

10+ Year Member



Hi guys, I really need your help and experiance here. I've recently noticed that there are lots of hits in my referrer logs from forums, although there is apparently no link to me on the forum. I've figured out it is people hotlinking my images. The same sort of thing is happening with my files.

The question I've got for you is this, what is wrong with my .htaccess which means these people are not being sent to my 403 page (in case of .zip files) or being served by anti-hotlinking gif?


RewriteEngine on
# redirect non-www to www subdomain.
RewriteCond %{HTTP_HOST} ^mydomain\.org [NC]
RewriteRule (.*) http://www.mydomain.org/$1 [R=301,L]

redirect 301 /guestbook http://www.mydomain.org/phpBook

RewriteCond %{REQUEST_FILENAME} \.(avi¦mpg¦zip¦ZIP¦exe¦EXE)$ [NC]
RewriteCond %{HTTP_REFERER}!^$
RewriteCond %{HTTP_REFERER}!^http://(.*).mydomain.(.*)/.*$ [NC]
RewriteCond %{HTTP_REFERER}!^http://(.*).otherdomain.(.*)/.*$ [NC]
RewriteCond %{HTTP_REFERER}!^http://(.*).otherdomain.(.*)/.*$ [NC]
RewriteCond %{HTTP_REFERER}!^http://(.*).otherdomain.(.*)/.*$ [NC]
RewriteCond %{HTTP_REFERER}!^http://bloggersubdomain/*$ [NC]
RewriteCond %{HTTP_REFERER}!^http://(.*).otherdomain.(.*)/.*$ [NC]
RewriteRule (.*) http://www.mydomain.org/forbidden.html [R,NC]

RewriteCond %{REQUEST_FILENAME} \.(jpe?g¦png¦PNG¦jpg¦JPG)$ [NC]
RewriteCond %{HTTP_REFERER}!^$
RewriteCond %{HTTP_REFERER}!^http://(.*).mydomain.(.*)/.*$ [NC]
RewriteCond %{HTTP_REFERER}!^http://(.*).otherdomain.(.*)/.*$ [NC]
RewriteCond %{HTTP_REFERER}!google\. [NC]
RewriteCond %{HTTP_REFERER}!search\?q=cache [NC]
RewriteRule (.*) http://www.mydomain.org/stophotlink.gif [R,NC]

ErrorDocument 404 http://www.mydomain.org/not_found.html
ErrorDocument 403 http://www.mydomain.org/forbidden.html

Could you please help me, because this code only seems to filter out certain sites and not others. It's been driving me crazy for the last week. Thanks.

jdMorgan

10:29 pm on Jun 12, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I don't know, unless the referrer for the requests that get through are blank. In order to avoid blocking legitimate visitors, you have to allow blank referrers as you have done, so some requests *will* get through. This is a fundamental problem with referrer-based blocking, and there is no way around it except to use more sophisticated methods to defeat hotlinking. A search of these forums for "hotlinking" will turn up a lot more info.

Two methods which work better, but a the cost of added complexity, are renaming your images peridically (based on time) and using cookies to authorize image access.

Since we're here, I'd like to point out several inefficiencies and errors in the code you posted. The most serious error is one of syntax in your ErrorDocument directives. As written, they will always return a 302 redirect status instead of the desired 403 or 404. This is likely to cause you problems in the search engines. The other changes are simply efficiency-related. You should verify this behaviour using the server headers checker [webmasterworld.com].


# move filetype check to RewriteRule, and no need for upper and lowercase patterns if you use [NC]
# use shorter non-blank-check
RewriteCond %{HTTP_REFERER} .
# use more-efficient pattern for subdomain part, escape literal periods, no need for further pattern
RewriteCond %{HTTP_REFERER} !^http://([^.]*)\.mydomain\. [NC]
RewriteCond %{HTTP_REFERER} !^http://([^.]*)\.otherdomain\. [NC]
RewriteCond %{HTTP_REFERER} !^http://([^.]*)\.otherdomain\. [NC]
RewriteCond %{HTTP_REFERER} !^http://([^.]*)\.otherdomain\. [NC]
RewriteCond %{HTTP_REFERER} !^http://bloggersubdomain [NC]
RewriteCond %{HTTP_REFERER} !^http://([^.]*)\..otherdomain.(.*)/.*$ [NC]
# moved filetype check to rule, no need for external redirect, use [L] flag
RewriteRule \.(avi¦mpg¦zip¦exe)$ /forbidden.html [NC,L]
#
# move filetype check to RewriteRule, and no need for upper and lowercase patterns if you use [NC]
# use shorter non-blank-check
RewriteCond %{HTTP_REFERER} .
# use more-efficient pattern for subdomain part, escape literal periods, no need for further pattern
RewriteCond %{HTTP_REFERER} !^http://([^.]*)\.mydomain\. [NC]
RewriteCond %{HTTP_REFERER} !^http://([^.]*)\.otherdomain\. [NC]
RewriteCond %{HTTP_REFERER} !google\. [NC]
RewriteCond %{HTTP_REFERER} !search\?q=cache [NC]
# added to allow protection of .gif files without infinite rewrite loop
RewriteCond %{REQUEST_URI} !^/stophotlink\.gif$
# moved filetype check to rule, added gif filetype, no need for external redirect, use [L] flag
# (note that jpe?g matches either .jpg or .jpeg)
RewriteRule \.(gif¦jpe?g¦png)$ /stophotlink.gif [NC,L]
#
# corrected syntax to return specified error code rather than 302 redirect
ErrorDocument 404 /not_found.html
ErrorDocument 403 /forbidden.html

I changed the code to do internal rewrites instead of redirects. This "hides" the action of your hotlink protection, making it harder to see, and therefore, to work around.

Remember to flush your browser cache (Temporary Internet Files) before testing any change to your access-control code.

Jim

RockyB

9:41 am on Jun 13, 2005 (gmt 0)

10+ Year Member



Thanks very much for your reply, it's appreciated. Just one query though:

RewriteCond %{HTTP_REFERER}!^http://([^.]*)\..otherdomain.(.*)/.*$ [NC]

is differant from the other refferer lines. Is it supposed to be like that?

jdMorgan

3:16 pm on Jun 13, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



No, I just missed that one -- or the phone rang in the middle of working on it. You can delete everything off the end. The only difference is that it runs faster without the unnecessary "fluff" at the end.

RewriteCond %{HTTP_REFERER} !^http://([^.]*)\.otherdomain\. [NC]

Note also that if your only variations in subdomain are "www" versus non-www, then the following, more specific pattern would be more efficient:

RewriteCond %{HTTP_REFERER} !^http://(www\.)?otherdomain\. [NC]

Actually, your rules would not have worked at all if there was no subdomain in the requested hostname -- for example, if someone requested "http:mydomain.com/somefile.html". Let's fix all of them:

# move filetype check to RewriteRule, and no need for upper and lowercase patterns if you use [NC]
# use shorter non-blank-check
RewriteCond %{HTTP_REFERER} .
# use more-efficient pattern for subdomain part, escape literal periods, no need for further pattern
RewriteCond %{HTTP_REFERER} !^http://([^.]+\.)?mydomain\. [NC]
RewriteCond %{HTTP_REFERER} !^http://([^.]+\.)?otherdomain1\. [NC]
RewriteCond %{HTTP_REFERER} !^http://([^.]+\.)?otherdomain2\. [NC]
RewriteCond %{HTTP_REFERER} !^http://([^.]+\.)?otherdomain3\. [NC]
RewriteCond %{HTTP_REFERER} !^http://bloggersubdomain [NC]
RewriteCond %{HTTP_REFERER} !^http://([^.]+\.)?otherdomain4\. [NC]
# moved filetype check to rule, no need for external redirect, use [L] flag
RewriteRule \.(avi¦mpg¦zip¦exe)$ /forbidden.html [NC,L]
#
# move filetype check to RewriteRule, and no need for upper and lowercase patterns if you use [NC]
# use shorter non-blank-check
RewriteCond %{HTTP_REFERER} .
# use more-efficient pattern for subdomain part, escape literal periods, no need for further pattern
RewriteCond %{HTTP_REFERER} !^http://([^.]+\.)?mydomain\. [NC]
RewriteCond %{HTTP_REFERER} !^http://([^.]+\.)?otherdomain\. [NC]
RewriteCond %{HTTP_REFERER} !google\. [NC]
RewriteCond %{HTTP_REFERER} !search\?q=cache [NC]
# added to allow protection of .gif files without infinite rewrite loop
RewriteCond %{REQUEST_URI} !^/stophotlink\.gif$
# moved filetype check to rule, added gif filetype, no need for external redirect, use [L] flag
# (note that jpe?g matches either .jpg or .jpeg)
RewriteRule \.(gif¦jpe?g¦png)$ /stophotlink.gif [NC,L]
#

See the regular expressions tutorial cited in our forum charter for more info on the regex patterns.

Jim

RockyB

2:49 pm on Jun 14, 2005 (gmt 0)

10+ Year Member



Excellent, thank you so much. Since changing that code far fewer request are getting through, which is more a moral victory than anything else, but it is very useful to me.

Thanks again.