Prevent Web Form Spam Without Captcha

October 31, 2019


Add in an unecessary field (hidden from human) to trick the bot to fill up the field. If the field is sent to the server, it is assumed to be spam.

<input id="inputAgree" type="checkbox" name="agree" autocomplete="off">

#inputAgree {
    display: none !important;

The following is a full example using Bootstrap.

    <div class="form-row justify-content-md-center">
        <div class="col-md-auto mb-3">
            <label for="inputEmail" class="sr-only">Your email</label>
            <input name="email" type="email" id="inputEmail" placeholder="Your email" value="" class="form-control">
        <div class="col-md-auto mb-3">
            <div class="form-check sr-only d-none">
                <input type="checkbox" id="inputAgree" autocomplete="off" checked="checked" class="form-check-input">
                <label for="inputAgree" class="form-check-label">I agree with the TOS</label>
        <div class="col-md-auto mb-3">
            <button type="submit" class="btn btn-primary">Subscribe</button>

Dynamic Field

Attached a onfocus and onblur event to the input field, and fill up an additional field like timestamp when such event happened.

On the server side, check for the timestamp and make sure it is within range (maybe 1h plus and minus).

NOTE: JavaScript Get Current Datetime in UTC

Store and Check IP Address

Store IP address from each form request, and start to block IP address if too many request from the same IP.

NOTE: You might consider blocking the IP without raising an error, to prevent alerting the spammer of the detection.

NOTE: Cloud Functions/Flask Get Client Ip Address (Python)

HMAC Signature

Generate HMAC Sign for all or certain form parameters, and verify the signature on the server.

Akismet API

NOTE: I have yet to try this.


If all else fail, use

This work is licensed under a
Creative Commons Attribution-NonCommercial 4.0 International License.