Pete Freitag Pete Freitag

Battling Comment Spam

Published on January 31, 2007
By Pete Freitag
coldfusionweb

Fighting comment spam seams like a never ending battle. I've done a lot over the last few years to try and squash it on my blog.

I started out by implementing a list of words that would trigger the comment to be blocked. I found myself updating this list on a weekly basis, never staying on top of it.

I solved that problem by implementing the Bayesian Filter CFC from fusionKit. The bayes filter has worked really well, and produced a suprisingly low number of false positives.

Now just over the weekend I was flodded with a ton of comment spams that were written well enough to get past the bayes filter. They were also all submitted within a few minutes, so there was no time to train my bayes filter.

I'm not a big fan of statically blocking IP addresses, since the owners of IP addresses can change over time. However I think temporary blocks on IP's are OK, so I wrote a little rate limiter that will block IP's that try to post more than 1 comment within a 5 minute time span or IP's that have attempted to post a large number of comments.

I'm sure some of you have probably experienced the same problem, so here you go:

<cfif IsDefined("application.rate_limiter")>
  <cfif StructKeyExists(application.rate_limiter, CGI.REMOTE_ADDR)>
    <cfif application.rate_limiter[CGI.REMOTE_ADDR].attemps GT 1 AND DateDiff("n", application.rate_limiter[CGI.REMOTE_ADDR].last_attempt, Now()) LT 5>
      <p>You are posting too many comments too fast, please slow down and wait 5 min.</p>
      <cfset application.rate_limiter[CGI.REMOTE_ADDR].attemps = application.rate_limiter[CGI.REMOTE_ADDR].attemps + 1>
      <cfset application.rate_limiter[CGI.REMOTE_ADDR].last_attempt = Now()>
      <cfabort>
    <cfelseif application.rate_limiter[CGI.REMOTE_ADDR].attemps GT 20>
      <p>You have made too many attempts to post a comment. Please try back in a few days.</p>
      <cfset application.rate_limiter[CGI.REMOTE_ADDR].attemps = application.rate_limiter[CGI.REMOTE_ADDR].attemps + 1>
      <cfset application.rate_limiter[CGI.REMOTE_ADDR].last_attempt = Now()>
      <cfabort>
    <cfelse>
      <cfset application.rate_limiter[CGI.REMOTE_ADDR].attemps = application.rate_limiter[CGI.REMOTE_ADDR].attemps + 1>
      <cfset application.rate_limiter[CGI.REMOTE_ADDR].last_attempt = Now()>
    </cfif>
  <cfelse>
    <cfset application.rate_limiter[CGI.REMOTE_ADDR] = StructNew()>
    <cfset application.rate_limiter[CGI.REMOTE_ADDR].attemps = 1>
    <cfset application.rate_limiter[CGI.REMOTE_ADDR].last_attempt = Now()>
  </cfif>
<cfelse>
  <cfset application.rate_limiter = StructNew()>
  <cfset application.rate_limiter[CGI.REMOTE_ADDR] = StructNew()>
  <cfset application.rate_limiter[CGI.REMOTE_ADDR].attemps = 1>
  <cfset application.rate_limiter[CGI.REMOTE_ADDR].last_attempt = Now()>
</cfif>


spam comments comment spam bayesian bayes

Battling Comment Spam was first published on January 31, 2007.

If you like reading about spam, comments, comment spam, bayesian, or bayes then you might also like:

Fixinator

The Fixinator Code Security Scanner for ColdFusion & CFML is an easy to use security tool that every CF developer can use. It can also easily integrate into CI for automatic scanning on every commit.


Try Fixinator

CFBreak
The weekly newsletter for the CFML Community


Comments

Pete, check out this project from Jake Munson cfformprotect.riaforge.org
by Jason Troy on 01/31/2007 at 3:10:52 PM UTC
Have your tried the CFAkismet CFC?

http://devnulled.com/cfakismet

We put it on our blog (http://blog.d-p.com) and love it.
by jonese on 01/31/2007 at 3:16:13 PM UTC
@Pete:

You might want to adjust the 1 comment per 5 minutes to at least 2 commments. 1 seems a little to strict--especially in the case where someone wants to post an addendum to what they typed.
by Dan G. Switzer, II on 02/01/2007 at 7:47:30 AM UTC
Hey Dan,

Actually it does allow for two comments since it says GT 1 and the attempts are incremented after that point. I wasn't clear about that in my post however. Thanks for pointing that out.
by Pete Freitag on 02/01/2007 at 8:10:35 AM UTC
I can understand your code. Could you give me the PHP version please
by idwebtemplate on 05/04/2007 at 12:56:09 AM UTC
Great site!e
by Bob on 08/14/2007 at 10:15:14 PM UTC
Good luck with your site in the future!e
by Bob on 08/23/2007 at 8:49:40 PM UTC
Good job, here and there!k
by Tim on 10/12/2007 at 5:30:16 AM UTC
Its like trying to control the weather, at this point, mother nature is gonna do what she wants to do. ,
by Daddy49 on 10/22/2009 at 7:12:02 AM UTC
Hi,

I have a question for the webmaster/admin here at www.petefreitag.com.

May I use part of the information from your post above if I provide a link back to your site?

Thanks,
John
by bidou on 11/10/2010 at 8:17:52 PM UTC
I have a blog (Fugitive Seeking Truth) and have had a number of my posts comment-spammed with the same comment that appears several times on this page:

"Thanks for sharing the link - but unfortunately it seems to be down? Does anybody here at [my blog address] have a mirror or another source?" with a name attached.

I also have the comment requesting permission to backlink. Any idea who posts these comments and why?

Thanks,

Blessings and peace,
Ylanne
by Ylanne S. on 03/18/2011 at 2:04:17 AM UTC