Anti-spam CSS honeypot

📄 BetterWays.dev wiki page | 🕑 Last updated: Feb 6, 2022

If you put an unprotected form (i.e. a contact form) on the open web, you'll soon start to get crazy amounts of spam.

One method to combat that is a CSS honeypot. The idea is to include in your form an additional input element, which will be hidden with CSS. That means that real users won't see it, but most of the bots are dumb enough to fill it in.

Then on the server-side, you just need to check if the value was filled in, and act accordingly.

An example: client side

I'll use "skip_me" as the name of the field, but you can use anything you like. Obvious names/labels like that may help users who are using assistive technologies, but they may also help bots.

<form method="POST">
...
<input type="text" name="skip_me" style="display: none;">
...
</form>

In the more realistic case, you'll probably want to include the label and define display: none; on the form-row level in the external CSS file.

Server side

JavaScript, express-like example:

//validate form

if(!req.body.skip_me) sendMail();

//return response

As you can see, the idea is very simple to implement in any language/environment.

If skip_me is not empty, we're simply skipping the sendMail() step and the spam bot will have no way of knowing that their message went into the void - they'll get the normal success response.

The principle is the same for SPA and traditional server rendering - it's just the matter of returning the JSON or HTML in the last step.


Note: I used this method in the past and it worked well. There are many variations of this method, I implemented something very similar to the above recently on DS, I'll put an update on effectiveness once I have more data.


Comments and suggestions

You can use this form to submit a suggestion or a comment.

If you find this site useful, please consider supporting it. Supporters also get access to some extras.