본문 바로가기

Story/Server

Referrer Checking with .htaccess

반응형

Referrer Checking with .htaccess

Referrer checking is a mechanism to restrict the way web resources are used. Specifically, you can use this technique to insist that files only be viewed from a specific page or site (or, rather, only viewed if the browser says that it’s viewing the file on your site, truthfully or otherwise).

Normally you would set up a referrer check in an htaccess file like this:

RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://www.mysite.com/.*
RewriteRule .*\.pdf - [NC,F]

 

The first line turns on rewriting, the second checks to see if the “REFERER” header (yes, spelled that way) does not start with “http://www.mysite.com/”, and the third line marks all files ending in “.pdf” as forbidden.

That’s nifty and useful and all, but it’s site-specific. You have to change the code to match your domain, and sometimes the exact same code needs to be applied across multiple domains. It’d be nice to check to see if the REFERER header contains the same domain name as the HOST header.

Ideally, you could do something like this:

# This doesn't work

 

RewriteCond
%{HTTP_REFERER} !^http://%{HTTP_HOST}/.*

 

Sadly, you’re not allowed to compare one server variable against another in a RewriteCond. We can work around this restriction by putting both variables on the same side of the condition, and then comparing the result against itself. Like so:

# This one works -- feel free to copy it onto your own site.

 

RewriteEngine
On RewriteCond %{HTTP_HOST}@@%{HTTP_REFERER} !^([^@]*)@@https?://\1/.* RewriteRule .*\.pdf [NC,F]

 

This may be a bit confusing at first, so let’s reason through it. On the left-hand side of the comparison, we have %{HTTP_HOST}@@%{HTTP_REFERER}. So for example, that would result in a string like this: tltech.com@@http://tltech.com/info. On the right-hand side of the validation rule, “^([^@]*)” means “remember everything before the first @ sign. Then we skip over the @@http:// (or optionally @@https://). Then make sure that the next bit matches the host name we remembered at the start. Then we make sure that’s followed by a / sign. And that’s it.

Essentially, this rule checks to see if the host name in the HTTP_REFERER field is exactly the same as the hostname in HTTP_HOST. And if that’s not the case, then the last line tells apache to block the specified file type.

Cool, eh? The best part is that you can cut-and-paste the code into any host without having to change anything about it. Just make sure that last line matches the file type or name that you want to restrict, and you’re golden.

반응형