Forum Moderators: phranque

Message Too Old, No Replies

Same-page sexy lovely gets too much attention

(a.k.a. Rewrite 2 hijacked graphics from 1 site?)

         

Pfui

5:34 am on Feb 21, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



There's a very large site where a poster hotlinked two of our graphics. Also in the post (and on others of their pages) is a text link to our site -- that's okay -- plus terrific images of a lovely celebrity, the latter resulting in an ever-increasing amount of hijacked-graphic hits.

Thing is, if I completely block the site as a referrer, I also lose anyone actually clicking the text links. (I'm already blocking the hotlinks.) From the looks of my logs, most people are loading the post but not following the text link.

Anyway, here's the dynamic URL the rewriting of which has got me stumped:

http:// www.badsite.com/board/showthread.php?t=123456
http:// www.badsite.com/board/showthread.php?t=123456&page=1

I did write the site x2, asking them to please edit the post and remove the hotlinks, but thus far they've done nothing. So what I'd like to do now is send a 1-pixel tracking GIF for each hit.

Here's my idea, as yet untested because my site is very busy. There are spaces between all } and!:

## badsite.com hotlink redirect 
RewriteCond %{HTTP_REFERER}!^$
RewriteCond %{HTTP_REFERER}!^http://(www\.)?mysite.com/.*$ [NC]
RewriteCond %{HTTP_REFERER}!^http://mysite.com/.*$ [NC]
RewriteCond %{REQUEST_URI}!^/graphics/hijacked\.gif
RewriteCond %{HTTP_REFERER} ^http://(www\.)?badsite\.com/board/showthread\.php(.*)$ [NC]
RewriteCond %{HTTP_REFERER} ^http://badsite\.com/board/showthread\.php(.*)$ [NC]
RewriteCond %{REQUEST_URI} ^/graphics/myimageA\.gif [OR]
RewriteCond %{REQUEST_URI} ^/graphics/myimageB\.gif
RewriteRule \.gif$ /graphics/hijacked.gif$ [NC,R=302,L] # is R=403 doable?

Thoughts, please? Thanks!

.
P.S.
If/when the other site does nothing and I decide to stop tracking the hijack hits, is this Rule okay instead?

RewriteRule \.gif$ - [F] 

jdMorgan

7:35 am on Feb 21, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



This is too complicated in two ways, and not complicated enough in one way. Let's comment the code (a very good practice) and find out why:

#1 If the referrer is not blank
RewriteCond %{HTTP_REFERER} !^$
#2 and if the referrer is not www.mysite.com or mysite.com
RewriteCond %{HTTP_REFERER} !^http://(www\.)?mysite.com/.*$ [NC]
#3 and if the referrer is not mysite.com
RewriteCond %{HTTP_REFERER} !^http://mysite.com/.*$ [NC]
#4 and if the requested URI is not /graphics/hijacked\.gif
RewriteCond %{REQUEST_URI} !^/graphics/hijacked\.gif
#5 and if the referrer is a page generated by /board/showthread\.php (plus anything), from www.badsite.com or badsite.com
RewriteCond %{HTTP_REFERER} ^http://(www\.)?badsite\.com/board/showthread\.php(.*)$ [NC]
#6 [b]and[/b] if the referrer is a page generated by /board/showthread\.php (plus something), from badsite.com
RewriteCond %{HTTP_REFERER} ^http://badsite\.com/board/showthread\.php(.*)$ [NC]
#7 and ( if the requested URI is /graphics.myimageA.gif ...
RewriteCond %{REQUEST_URI} ^/graphics/myimageA\.gif [OR]
#8 ... [b]or[/b] the requested URI is /graphics/myimageB.gif )
RewriteCond %{REQUEST_URI} ^/graphics/myimageB\.gif
# then externally redirect to /graphics/hijacked.gif
RewriteRule \.gif$ /graphics/hijacked.gif$ [NC,R=302,L]

Let's take care of the referrer logic first. To begin with, the first RewriteCond isn't needed, because the fifth RewriteCond requires that the referrer be specifically www.badsite.com or badsite.com. If it's either of those, then by definition, it cannot be blank. So let's get rid of this line.

Next, the second RewriteCond isn't needed for the same logic reason. If the fifth RewriteCond requires the referrer to be badsite.com, then obviously, the referrer won't be 'mysite.com.' So, RewriteCond #2 is redundant. There's also a bit of unnecessary fluff on the end -- the ".*$" after the ".com" serves no purpose whatsoever, and is equivalent to just quitting after ".com", leaving off the pattern and the end-anchor.

RewriteCond number three is redundant for the same reasons as RewriteCond #2. In addition, it's redundant with RewriteCond #2 itself. (The (www\.)? in RewriteCond #2 means that "www." or blank is an acceptable match.) So this RewriteCond can be removed as well.

RewiteCond number four is redundant because RewriteConds #7 and #8 require that one of two specific images be requested before the rewrite takes effect. So RewriteCond #4 is not needed. If the request meets the requirements of RewriteConds #7 or #8, then it must also meet this RewriteCond as well. Bye bye, #4.

RewriteCond #5 is OK, except the the (.*) at the end will match anything (or nothing).

RewriteCond #6 is redundant with RewriteCond #5. However, there's also a logical error here: Without an [OR] flag on RewriteCond #5, you are requiring the referrer to be (www.badsite.com or badsite.com) AND also to be badsite .com -- so only badsite will ever be accepted, and requests from www.badsite will sail on past your rule. This line has to go!

RewriteConds #7 and #8 are OK, but you can probably combine these using a pipe-OR in the RewriteRule itself, thus saving some processing time. Note that RewriteConds are not processed unless the requested URI matches the RewriteRule pattern. Yes, the pattern match part of a RewriteRule is actually processed first, before any of the preceding RewriteConds are evaluated! (See the mod_rewrite documentation or the source code if you don't believe this.)

Now we get to the rule, which is a mixture of internal rewrite and external redirect syntax. It should work -- on most servers. But it won't work on all servers. It's best to include the http protocol specifier and the canonical domain with all external redirects to avoid problems now, or with future code portability. (The problem can arise with certain combinations of the HTTP-requested domain and the ServerName and UseCanonicalName server settings.)

So what's that leave after all this critical chopping and hacking? This:


# If the referrer is a page generated by /board/showthread\.php (plus something), from www.badsite.com or badsite.com
RewriteCond %{HTTP_REFERER} ^http://(www\.)?badsite\.com/board/showthread\.php [NC]
# then redirect myimageA and myimageB requests to the alternate image
RewriteRule ^graphics/(myimageA¦myimageB)\.gif$ http://mysite.com/graphics/hijacked.gif [R=302,L]

So, it really takes only two lines of code to replace all of that above, after the logical redundancies have been removed. But one problem remains -- that specific thread bit that wasn't handled at all. We need to look at the query string in the referrer to detect that specific referring thread:

# If the referrer is a page generated by /board/showthread\.php (plus the thread I don't like), from www.badsite.com or badsite.com
RewriteCond %{HTTP_REFERER} ^http://(www\.)?badsite\.com/board/showthread\.php\?([^&]+&)*t=123456(&¦$) [NC]
# then redirect myimageA and myimageB requests to the alternate image
RewriteRule ^graphics/(myimageA¦myimageB)\.gif$ http://mysite.com/graphics/hijacked.gif [R=302,L]

and if you prefer it without the comments:

RewriteCond %{HTTP_REFERER} ^http://(www\.)?badsite\.com/board/showthread\.php\?([^&]+&)*t=123456(&¦$) [NC]
RewriteRule ^graphics/(myimageA¦myimageB)\.gif$ http://mysite.com/graphics/hijacked.gif [R=302,L]

To explain the query string pattern, "\?([^&]+&)*t=123456(&¦$)", that's "a literal question mark, followed by (one or more characters not equal to an ampersand, followed by an ampersand) as many times as you like --including zero times-- followed by "t=123456", followed immediately either by an ampersand (and anything else) or by the end of the line. This extra stuff ensures that the pattern won't mis-match if the query string contains "tt=123456" or "t=1234567", and that the order of the query string name/value pairs won't matter, either.

So there it is. Hopefully, a lot simpler and clearer -- and even more hopefully, now without typos. :)

Change the broken pipe "¦" characters above to solid pipe characters before use; Posting on this forum modifies them. Flush your browser cache after any change to your .htaccess or httpd.conf file.

Jim

jdMorgan

8:01 am on Feb 21, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



... And yes, you can change the final rule to

RewriteRule ^graphics/(myimageA¦myimageB)\.gif$ - [F]

if you like, as long as you mark your 403 error page as non-cacheable. If it is cacheable, then anyone who has viewed the hotlinking page will always see the hijacked.gif image --until they flush their browser cache or until their cached image expires-- even if they come to your site to view that image from your pages.

Jim

Pfui

9:07 am on Feb 24, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Masterfully explained, thank you! "The check's in the mail."

: )