Spam comes in may forms.

I had been noticing some odd traffic appearing in my referrer logs from “buttons-for-website.com”, and a few other places. Odd, I thought, but I wasn’t too concerned.

A client recently asked me about it, since similar traffic was starting to appear in their analytics for a brand new site. I did a little bit of research, and it turns out that this is actually a spam attack.

Basically, the spammer hits your site and sets a referrer header containing a url and their spam message (keywords + another url, usually). Since a small percentage of sites make their referrer logs public (either deliberately or through misconfiguration), when these are indexed, they can be used to game the search engine of the site they’re trying to boost.

Stopping the spam with mod_security

I don’t like spammers, and it was starting to make my logs (and those of my client’s) a little noisy. So, I decided to do something about it. So, using mod_security, I added a couple of simple rules, which would drop the traffic where the referrer contained certain keywords.

Simple, but effective:

This seemed to put an end to the worst of it.

I also noticed that a few spammers were posting with obvious spam keywords in the referrer header, so I added a similar rule to block those for good measure:

Testing

To test your rules, you can use curl to hit your site and send a triggering referrer, e.g.

Or

Hope that helps!

6 thoughts on “Blocking referrer spam with mod_security

  1. Yeah, happened to me in a recent upgrade (to latest debian)… basically mod-security was updated, and now requires a rule ID (quite sensible really – helps debug problems).

    Simply add a unique numeric ID in the rule definition. Pick a suitably high number to avoid collisions, e.g. I started my referrer spam rules with 90001… so the example rules become:

  2. I’ve the latest modsecurity but the code doesn’t block this. Can you help me with the right code?

    SecRule REQUEST_HEADERS:Referer “^https?://(www\.)?.amazonaws\.com/?” “id:90001,phase:1,log,deny,auditlog,status:503,msg:’Referer spam1′”
    SecRule REQUEST_HEADERS:Referer “^https?://(www\.)?.googlebot\.com/?” “id:90002,phase:1,log,auditlog,deny,status:503,msg:’Referer spam2′”
    SecRule REQUEST_HEADERS:Referer “^https?://(www\.)?.msn\.com/?” “id:90003,phase:1,log,auditlog,deny,status:503,msg:’Referer spam3′”

  3. Only thing I can see is you’ve got a “.” between the (www\.)? and the rest… this means it’s looking for http(s)://www..msn.com or http(s)://.msn.com

  4. Hi Marcus, thx for your help.
    What I need is something like this. I prefer SecRule Block4 but these rules doesn’t work.

    SecRule REQUEST_HEADERS:Referer “^https?://(www\.)?amazonaws\.?$” “id:17004,phase:1,log,auditlog,t:none,deny,status:503,msg:’Block4′,logdata:’%{REQUEST_HEADERS.User-Agent}, iphostname:%{ip.hostname}, IPnr=%{remote_addr}, Portnr=%{server_port}'”
    SecRule REQUEST_HEADERS:Referer “^https?://(www\.)?amazonaws\.com$” “id:17003,phase:1,log,auditlog,t:none,deny,status:503,msg:’Block3′,logdata:’%{REQUEST_HEADERS.User-Agent}, iphostname:%{ip.hostname}, IPnr=%{remote_addr}, Portnr=%{server_port}'”
    SecRule REQUEST_HEADERS:Referer “^https?://(www\.)?amazonaws\.com/?” “id:17002,phase:1,log,auditlog,t:none,deny,status:503,msg:’Block2′,logdata:’%{REQUEST_HEADERS.User-Agent}, iphostname:%{ip.hostname}, IPnr=%{remote_addr}, Portnr=%{server_port}'”
    SecRule REQUEST_HEADERS:Referer “^https?://(www\.)?amazonaws\.?/?” “id:17001,phase:1,log,auditlog,t:none,deny,status:503,msg:’Block1′,logdata:’%{REQUEST_HEADERS.User-Agent}, iphostname:%{ip.hostname}, IPnr=%{remote_addr}, Portnr=%{server_port}'”
    SecRule REQUEST_HEADERS:Referer “^https?://(www\.)?amazonaws\.?/$” “id:17000,phase:1,log,auditlog,t:none,deny,status:503,msg:’Block0′,logdata:’%{REQUEST_HEADERS.User-Agent}, iphostname:%{ip.hostname}, IPnr=%{remote_addr}, Portnr=%{server_port}'”
    RS.User-Agent}, iphostname:%{ip.hostname}, IPnr=%{remote_addr}, Portnr=%{server_port}'”

Leave a Reply