It started slowly. Every few days I’d have a suspicious looking username pop up in my user list. I thought little of it at first — It’s free to register at Darkadia (my game cataloging service), and, beyond what’s intended, there’s nothing untoward you can do once you’ve logged in. So not a big worry.

But over time the frequency of these spam registrations increased. Now I was getting five or more per day. Finally I got curious enough and decided to try and find out exactly how many of my site’s users were genuine. I did this with a simple database query which showed me how many of my registered users had never returned after that initial registration and login. I was shocked. By my estimates, fully a third of my entire user base were spam registrations.

Something had to be done.

I suppose your first thought at this point might be to simply add a CAPTCHA. But there are few things I hate more on the web than trying to figure out what illegible numbers and letters have been smudged onto those CAPTCHA images. I was not going to inflict that pain on real people in order to thwart a registration bot.

Nope, I was going to need something a little more subtle than that. My attack on spambots would be threefold:

1. Block the offending domains

I noticed that a lot of the spam registrations were making use of email addresses from the domains big-post.com and mail-4server.com. If those had been Gmail or Hotmail addresses I might have left it at that, but as I did not have a single valid user from either of the offending domains, l felt it’d save me a lot of hassle to simply ban those domains outright. This ability is built right into Drupal. I went to the Access Rules section in the admin panel (admin/user/rules), and added a DENY rule for each of the domains. The rule configuration takes a wildcard, so I could simply enter %@big-post.com and %@mail-4server.com.

Update

Thanks to @typhonius for pointing out in the comments that the access rules functionality has been removed from the Drupal 7 core. It is now provided by the User restrictions module.

2. Filter out the bots without annoying my users

For this I turned to a great little module called Spamicide, which lays an effective honeypot trap for the spambots. It adds an input field to your registration form that is hidden from your users, but visible to spambots. When the field is filled in, the registration attempt is rejected. Spamicide supports any form on a Drupal website and, with some measures built in to avoid detection, it works a treat — in the three months since I turned it on, it’s blocked over 900 registration attempts.

3. Require email verification

Implementing the first two measures dramatically reduced the number of spam registrations I was receiving. But it didn’t quite get rid of all of them. And now that I had the bit between my teeth, I couldn’t just let it lie there. Nevertheless, requiring my visitors to verify their emails was a tough decision, because it was going to be an inconvenience. Ultimately though, I just wasn’t comfortable with the idea of having spambots with valid accounts on my site — I could well implement some change in the future that could give spammers free reign to ply their trade.

Drupal supports email verification out of the box, so if you’re happily using that you can skip the rest of this section. But what if you want users to choose their password during registration? You can’t have it both ways with Drupal running in its standard configuration — you either have email verification enabled, or you disable that to let new users choose their password. But the problem with letting them choose their password is that anyone can register using any bogus email address and now they’re a fully authenticated user of your system and, depending on how your permissions are configured, they can start spamming you to death.

Enter LoginToboggan. This module modifies Drupal’s login system in a number of ways and you can check the project page for a full rundown. What we’re interested in though, is that it allows you to require email verification AND let users choose their own passwords. It does this by assigning the new user a role with a minumum set of permissions, and automatically upgrading the user once the email address is verified. You can even set it to delete unverified accounts after a set interval.

Conclusion

Completing step 3 was the final nail in the spammers’ coffin; at least as far as Darkadia is concerned. I’m convinced the above measures will stop all spambots, and all but the most determined of spammers. And most importantly, I didn't have to penalise my own users just to make life difficult for spammers.

Alternatives

Mollom is a popular option for preventing spam on your Drupal site. It works by employing a learning algorithm to determine whether a registration attempt or comment posted is genuine.

Update

The Honeypot module provides the same form protection as Spamicide, but it also adds a timestamp-based deterrent that ensures a small amount of time has passed between page load and form submission. It is in use on drupal.org, so is clearly a solid option. (Thanks to @servercheck for pointing this out in the comments.)