← Home

How to add a floodgate to Mephisto's nearly perfect spam protection

[Update]

This little anti-spam trick has been that efficient that I have had no blog comment spam so sort out for months (still counting). I therefore decided to "upgrade" to a slightly more sophisticated version (re-allowing commenters to add an email address) and re-vamped the whole thing as a more distributable Mephisto plugin instead of two shaky patches.

I'm going to put some notes about the new plugin asap. I've added an article about the plugin now: "Inverse Captcha Anti-Comment-Spam Technique: Now A Regular Mephisto Plugin".

You may also want to refer to this page for additional information: Mephisto Inverse Captcha Anti-Comment-Spam Plugin.

The idea

When I was running Typo last year I recieved almost no spam at all! The reason for this was that Typo had a preference that allowed you to only accept comments that were posted through Ajax. None of the default-dumb-ass spam bots seem to be able to recognize this and act accordingly. Of course a moderately skilled spammer could easily have cracked this "protection" ... but actually nobody seemed to care - and that's the point.

With this in mind and for a quick test run I monkeypatched an "inverse captcha" mechanism right into this very Mephisto installation that you're looking at. (I prefer the term "inverse" because "negative" sounds negative.)

What's happening is nothing more than that the email form field is hidden through simple CSS. The normal user won't see it. But bots will fill them in. If a human user happens to use some kind of super-exotic browser and read my blog and wants to comment on it he will also see a short notice that advises him not to fill in the email field. So this fallback mechanism can even count as a simple form of a Touring test as well.

Of course this is not perfect. I hope that it will act as a front flood gate that keeps out the vast majority of dumbness though - and in the light of my Typo experiences that's something like 99% of all spam.

The rest will be spotted by Akismet and packed away by Mephisto anyway as it happens now! Thus I hope to find only a very small number of spammy comments in my admin section after another 30 days and I'll happily check and deleted them then! Whatever results I'll see I'll keep you posted :-)

Howto implement something like this?

That's super easy. On the controller side all you need to change is one line in the MephistoController's dispatch_comments action:

line 47    @comment.save!

now reads:

line 47    @comment.save! if @comment.author_email.blank?

(One might argue that this behaviour counts in as a business rule and because we want to marry "fat models" with "thin controllers" we'd better move this to the Comment model. That's right. But we can leave this for later refactoring and go with the "simplest thing that could possibly work" here for now.)

Here's a patch that does just this: inverse_captcha.diff

But obviously this alone would leave most of your users run into a concrete wall. Additionally we'll need to update our view accordingly and also hide the author_email field in the comments form through CSS like this:

#comment-email {
  display: none;
}

Also, like mentioned above, I've added a short notice that asks people to not fill in the email field. I don't think it will ever be seen at all. But otherwise it will prevent people from being locked out for no obvious reason.


<p id="comment-email">
  If you can read this, you don't use a typical webbrowser that plays
  nice with CSS. <br />
  <strong>Please do not fill in an e-mail address then!</strong><br />
   <label for="author_email">E-Mail</label>
</p>

Here's another patch that I've filed away for my personal backup: inverse_captcha_theme.diff. Obviously it will only work with my own theme.

What do you think?

PS: If you're interested in the results of this experiment you might want to have a look at my follow-up article: Report: 30 days with no blog spam on Mephisto!