4

Been surfing around for a solution for a couple days now.

How do I enable Apache hotlink protection without hardcoding my domain in the config file so I can port the code to my other domains without having to update the config file every time?

This is what I have so far:

RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?example\.(com|net|org) [NC]
RewriteRule \.(gif|ico|jpe|jpeg|jpg|png)$ - [NC,F,L]

... And this is what Apache suggests:

SetEnvIf Referer example\.com localreferer
<FilesMatch \.(jpg|png|gif)$>
    Order deny,allow
    Deny from all
    Allow from env=localreferer
</FilesMatch>

... both of which hardcode the domain in their rules.

The closest I came to finding any info that covers this is right here on ServerFault, but the conclusion was that it cannot be done. Based on my research, that appears to be true, but I didn't find any questions or commentary dedicated soley to this question.

If anyone's curious, here is the link to the Apache 2 docs that cover this topic.

Note that Apache environment variables (e.g. %{HTTP_REFERER}) cannot be used in the RewriteCond's CondPattern argument.

Jeff
  • 1,406
  • 3
  • 26
  • 46

1 Answers1

2

What about checking to see if Host matches the Referrer? E.g.

RewriteCond %{HTTP_REFERER} !%{HTTP_HOST}

Edit

This won't work, as stated by the OP. For Apache 2.4 you can use:

RewriteCond expr "! %{HTTP_REFERER} -strmatch '*://%{HTTP_HOST}/*'"

For 2.2, you could write a small handler in mod_perl or mod_python that could perform the compare and issue the 403 error.

To achieve this with mod_python:

Create a file in your docroot (in my case /var/www/) called hotlink.py

from mod_python import apache

def headerparserhandler(req):
    if req.headers_in.get("Host") != req.headers_in.get("Referer"):
            return apache.HTTP_FORBIDDEN
    return apache.OK

In you Apache config:

 <Directory /var/www/>
   ...
   AddHandler mod_python .jpg
   AddHandler mod_python .gif
   PythonHeaderParserHandler /var/www/hotlink.py
   #PythonDebug On
 </Directory>

Now all requests for .jpg and .gif will be first checked by hotlink.py. With mod_python you can also check against the req.server.server_hostname attribute to check against ServerName instead of the incoming Host header.

Alastair McCormack
  • 2,184
  • 13
  • 22
  • Seems like it should work, right? Unfortunately, as the last sentence of my question points out, you can't use environment variables in the `RewriteCond`'s *CondPattern*. – Jeff Oct 11 '12 at 22:58
  • @Jeff Doh, I should have checked. I've just seen in Apache 2.4 redirect docs suggest something. I'll update my answer and think about 2.2. – Alastair McCormack Oct 11 '12 at 23:01
  • It seems to me that unless there is a way to compare `%{HTTP_REFERER}` with `%{HTTP_HOST}% on the `RewriteCond`'s *TestString* and then compare it to "something" (maybe even nothing!) on the same *CondPattern*, this simply can't be done with Ap2.2. – Jeff Oct 12 '12 at 00:21
  • @Jeff I should have read your post more carefully as you clearly stated that RewriteCond can't compare HTTP headers. The only way I can think to achieve this is by writing a handler in mod_python or mod_perl. – Alastair McCormack Oct 12 '12 at 09:02
  • Truly appreciate your effort. +1 and checkmark. – Jeff Oct 12 '12 at 13:13