Pete Freitag Pete Freitag

Battling Comment Spam

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>

Like this? Follow me ↯

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:

FuseGuard Web App Firewall for ColdFusion

The FuseGuard Web Application Firewall for ColdFusion & CFML is a high performance, customizable engine that blocks various attacks against your ColdFusion applications.

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