DadsFam AntiSpam

Description

DadsFam AntiSpam blocks spam on contact forms, comment forms, user registrations, logins and WooCommerce checkout — without making real visitors solve puzzles, and built so that a real person is never turned away by a guess.

Everything described below works on every site. Nothing is capped, blurred, disabled or time-limited.

Built never to lose a real customer

A spam filter that blocks one real customer has cost more than all the spam it stopped. So:

  • Only a message actually written to you gets the full set of checks. A sign-up, a login, an add-to-cart button or a signed-in member only meets the honeypot, your own blocklists and the public spam lists, and WooCommerce’s cart and checkout are left to WooCommerce.
  • A CAPTCHA, a missing CAPTCHA token or an unusual timestamp only adds points to the score. On its own it never blocks anyone.
  • The same message sent twice — to two people, or again after an error — is fine. Only the third identical copy to the same recipient counts as a repeat.
  • When a check that judges how a message arrived holds one that reads like a real person wrote it, it is emailed to you straight away instead of being lost, and the visitor is told it arrived.

How it stops spam

  • Honeypot trap — an invisible field is injected into your forms. Bots fill it in; real visitors never see it. The field name rotates daily so it cannot be learned, with a grace period so page caching does not break it.
  • Time check — a signed timestamp is added on page load. A submission that arrives faster than a human could type is refused.
  • Rate limiting — an address that submits repeatedly is throttled. Whitelisted addresses and logged-in staff are never counted, so testing your own form never locks you out.
  • Unlimited blocklists — block IPs (wildcard and CIDR supported), email addresses, domains, usernames and keywords. There is no entry limit.
  • Whitelist — addresses you trust are never blocked, never rate-limited, and can always log in. Always available, because it is what stops you locking yourself out.
  • Content scoring — excessive links, HTML injection and spam phrasing all add to a score you control.
  • Disposable email detection — throwaway addresses are rejected, and the domain is checked for a real DNS record.
  • Comment protection — the same checks applied to WordPress comment forms, with optional flagging of non-Latin comments.
  • Public spam lists (threat feeds) — the Spamhaus DROP and EDROP lists, StopForumSpam’s toxic networks and weekly address list, and the Tor exit list are downloaded to your server once a day and checked locally. No keys, no sign-up, and nothing about the visitor is sent anywhere. Off by default; the one-click setup recommends it.
  • StopForumSpam live lookup — optionally ask the StopForumSpam database whether this exact address or email account has been caught spamming elsewhere, with a confidence figure you set the bar for. Off by default because it shares the visitor’s IP and email with StopForumSpam.
  • Spam Brain — a self-learning classifier that learns from the spam the other checks confirm and from the real messages that get through, then nudges the score — up for wording that looks like your spam, down for wording that looks like your customers. It only learns from evidence about the message itself, it can only tip a message the fixed rules already find suspicious, and it stores one-way hashes of words, never the message. “This was not spam” in the log unteaches a mistake.
  • Never lose a real message — some checks judge how a message arrived (no script ran, it came from a network on a public spam list, the email address is a near-copy of gmail.com). When one of those holds a message that reads like a real person, it is emailed to you with Reply-To set to the sender, the visitor is told it arrived, and one link lets them straight through next time. At most ten a day, never the same message twice. On by default.
  • Autopilot — the Brain blocks attackers by itself. It reads the spam log and blocks the address, the network (256 addresses) or the whole range (65,536) a bot is working through, because a blocked bot usually just moves on to the next address along. Blocks run out on their own and come back longer if the attack does. It learns which networks your customers and staff use — logins, paid orders, approved comments — and never blocks those. It never touches logins or checkout, and your whitelist always wins. What it is blocking, and why, is on your dashboard with a one-click “Let back in”. On by default.
  • AI second opinion (optional) — on WordPress 7.0 and later, a message the rules are unsure about can be read by the AI service you connect once for your whole site under Settings Connectors (for example Anthropic’s Claude, Google’s Gemini or OpenAI). It says spam or real, how sure it is, and why. A confident “spam” blocks it and teaches the Brain; a very confident “real” lets a genuine customer through. It goes through the AI Client built into WordPress, so this plugin holds no AI key of its own. Only borderline messages are sent, never the visitor’s IP address or name, and a slow or failed answer changes nothing. Off by default.
  • Remote control — everything the plugin can do is published through the WordPress Abilities API (WordPress 6.9 and later), so an assistant such as Claude can answer “who is attacking the shop?”, “why was this blocked?” or “would this message get through?”, and block, unblock, whitelist, tune settings or run the Self-Test for you. Administrators only, with switches for what it may do and a log of everything it did.
  • Self-repair — checks itself every day, after every update and whenever you ask, and fixes what is safe to fix by itself: damaged settings, missing tables, two CAPTCHAs on one form, whitelist and blocklist clashes, a server locked out of its own site, an untrained Brain and public spam lists that stopped updating. It tells you what it fixed, and never switches a protection off to make a problem go away.
  • Optional CAPTCHA — Cloudflare Turnstile, hCaptcha or Google reCAPTCHA (v2 checkbox, v2 invisible or v3 scoring), on whichever forms you choose. Its answer is weighed with everything else: on a message it adds to the score, and on a checkout, a sign-up or a form plugin only an address that fails it five times in fifteen minutes is held back.
  • Full spam log — every block recorded with the reason in plain words, the address, form and time, searchable and filterable, with a one-click “this was not spam” that whitelists the sender and lifts any lockout.

Works with

Contact Form 7, WPForms, Ninja Forms, Gravity Forms, Fluent Forms, Pagelayer, WooCommerce, WordPress comments, and WordPress login, registration and lost-password forms. Custom and theme contact forms that have no dedicated integration are protected on the server by the generic form guard, including reCAPTCHA v3 verification.

Declared compatible with WooCommerce High-Performance Order Storage and Cart & Checkout Blocks.

Visitor IP detection

The visitor’s address is taken from the network connection, which cannot be forged. If your site sits behind Cloudflare, a load balancer or a reverse proxy, switch on “This site is behind a proxy” in Settings and choose which forwarded header to trust.

Cloudflare is recognised automatically. When a request arrives from one of Cloudflare’s published addresses, the real visitor address is read from the header Cloudflare adds — even with the proxy setting off — so a site behind Cloudflare can never mistake every visitor for Cloudflare itself.

This matters: a plugin that trusts a forwarded header by default can be defeated by anyone who sends a made-up one, which would let a blocked address straight through and reset its rate-limit allowance on every request.

Privacy

Out of the box no data is sent anywhere: there are no external calls, no tracking and no accounts. The spam log lives in your own database, and if you would rather not store email addresses, names or page URLs at all, switch off “Store submission details” and only the reason and timestamp are kept. The Spam Brain stores one-way hashes of words, never the message itself. The Autopilot keeps the address ranges of the attackers it blocks, and only one-way hashes of the networks your real visitors use — never a customer’s address. It makes no outside connections.

When “Never lose a real message” holds a message that reads like a real person, a copy is emailed to your site’s own admin address through your site’s normal email — the same way your contact form would have sent it.

Some optional features, each off by default, make outbound connections. They are described in full under External services below. In short: the threat feeds download public lists to your server on a schedule and send nothing about visitors; the StopForumSpam live lookup sends the visitor’s IP address and email address to StopForumSpam; the optional CAPTCHA (Cloudflare Turnstile, hCaptcha or Google reCAPTCHA — whichever you choose) loads that provider’s script in the visitor’s browser and sends the resulting token, your secret key and the visitor’s IP address to the same provider; and the AI second opinion sends only borderline messages — the message and its subject, the kind of form, the sender’s email domain and your site’s name, tagline and web address, never the visitor’s IP address or name — through WordPress’s AI Client to the AI service you connected under Settings Connectors.

A word about PRO

Right, let me be straight with you, because I hate being sold to as much as you do.

Everything above is free and it stays free. The honeypot, the time check, the blocklists, the public spam lists, the Spam Brain, the Autopilot, the AI second opinion, never losing a real message, the spam log, the self-repair and the remote control — none of those are premium features. Those are the things a spam plugin should just do, and if I put them behind a paywall I would be taking the mickey.

There is a PRO add-on. It exists because I am a dad in Cape Town, and this is one of the things that puts food on the table at my house. That is the honest reason. Not “unlock your potential”, not “supercharge your workflow”. Just: if this plugin kept the junk out of your inbox and you can spare it, PRO helps me keep building.

What PRO adds is for people who run more than one site or want a bit more reach: DadsFam Shield, where spam caught on one of your PRO sites is blocked on all of them and their Brains share what they learn, DNSBL reputation checks, country blocking for your forms, and a digest email of what was stopped. That is extra reach and convenience. It is not the plugin working properly, because the plugin already works properly.

So if the free one does everything you need, brilliant. Genuinely. Use it, and I hope your spam log stays boring. If you get to the point where your sites helping each other would save you time, PRO is at plugins.dadsfam.co.za.

Either way, thanks for using something I built. — Zak, DadsFam

External services

Out of the box this plugin connects to nothing. Each service below is optional, switched off by default, and used only after you switch it on in Anti-Spam Settings.

Public spam lists — FireHOL’s blocklist mirror on GitHub

What it is: a blocklist service, the way Akismet is an anti-spam service. Spamhaus, StopForumSpam and other volunteer projects publish the internet addresses that are sending spam and running attacks right now. The lists change several times a day, so they cannot be shipped inside the plugin; the FireHOL project collects them and keeps them current on GitHub. Your server downloads the lists and checks visitors against its own copy.

Setting: Anti-Spam Settings Threat intelligence Public spam lists, “Check visitors against the lists below”.

Server: raw.githubusercontent.com (GitHub). Each list is one file under https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/ — spamhaus_drop.netset and spamhaus_edrop.netset (Spamhaus DROP and EDROP), stopforumspam_toxic.netset and stopforumspam_7d.ipset (StopForumSpam), tor_exits.ipset (Tor exit nodes) and, only if you tick them, botscout_30d.ipset, firehol_webclient.netset, firehol_abusers_1d.netset and firehol_level1.netset.

Account: none — no sign-up and no key.

When: once a day, once about 20 seconds after you switch it on, when you press “Update now”, and when the daily self-check finds the lists more than three days old. Never while a visitor waits.

What is sent: a plain download request whose User-Agent names this plugin and its version. Nothing about your visitors, your site or your settings. Visitors are checked against the downloaded copy, on your own server.

Terms: GitHub Terms of Service https://docs.github.com/site-policy/github-terms/github-terms-of-service — GitHub Privacy Statement https://docs.github.com/site-policy/privacy-policies/github-general-privacy-statement — FireHOL https://iplists.firehol.org/ — Spamhaus DROP https://www.spamhaus.org/drop/ — StopForumSpam https://www.stopforumspam.com/ — BotScout https://botscout.com/

Throwaway email domains — the disposable-email-domains list on GitHub

What it is: the open disposable-email-domains project’s list of thousands of temporary and ten-minute email services. New ones appear every week, so the list is fetched rather than shipped; it extends the short list built into the plugin.

Setting: “Throwaway email domains”, one of the public spam lists above.

Server: raw.githubusercontent.com (GitHub) — https://raw.githubusercontent.com/disposable-email-domains/disposable-email-domains/main/disposable_email_blocklist.conf

Account: none.

When: together with the public spam lists above.

What is sent: the same plain download request, nothing else. Email addresses typed into your forms are checked against the downloaded list on your own server and are never sent anywhere.

Terms: the project and its licence https://github.com/disposable-email-domains/disposable-email-domains — GitHub Terms of Service and Privacy Statement as above.

StopForumSpam live lookup

What it is: StopForumSpam’s database of addresses and email accounts reported for spamming, fed by thousands of sites.

Setting: Threat intelligence “Look visitors up on StopForumSpam”.

Server: https://api.stopforumspam.org/api

Account: none.

When and what is sent: each form submission, registration or comment from a visitor who is not on your whitelist sends the visitor’s IP address and the submitted email address, and receives back whether each has been reported as a spammer and with what confidence. Answers are cached for six hours, so each visitor is looked up once. If the service is slow or unreachable the visitor is let through.

Terms and privacy: https://www.stopforumspam.com/legal

CAPTCHA — Cloudflare Turnstile, hCaptcha or Google reCAPTCHA

Setting: “Use a CAPTCHA”, then “Which service”. Only the one service you choose is used, and only on the forms you tick.

Account: a free account with that service, for the site key and secret key you paste into Settings.

When and what is sent: the visitor’s browser loads that service’s script on the forms you ticked, and your server sends …

Screenshots

Installation

  1. Upload the dadsfam-antispam folder to /wp-content/plugins/, or install through Plugins Add New.
  2. Activate the plugin. Sensible protection is on immediately.
  3. Go to Anti-Spam Settings to adjust anything.
  4. Before blocking any IP range, add your own address to the whitelist. Your current address is shown right there on the page.

FAQ

Will this block real customers?

It is built not to. Only a message written to you gets the full checks; sign-ups, logins, the cart, the checkout and signed-in members only meet the honeypot, your own blocklists and the public spam lists. A CAPTCHA result or a missing script only adds points — it never blocks anyone by itself — and the Spam Brain can only tip a message the fixed rules already find suspicious. The same message sent twice is fine. And if a check that judges how a message arrived holds one that reads like a real person, it is emailed to you instead of being lost, and the visitor is told it arrived.

What does a rescued message look like?

An email to your site’s admin address with the sender’s name, email, the page and their message, and Reply-To set to the sender so you can just reply. One link in it, opened while you are logged in, whitelists the sender and teaches the Brain the message was real. Switch it off under Settings Protection “Never lose a real message”.

I have locked myself out of wp-login. What now?

Add your address to the whitelist and you will be let straight back in — the whitelist is checked before any block, including at login. If you cannot reach the admin at all, remove the IP from dfsas_options in the database, or rename the plugin folder over FTP to switch it off temporarily.

Does it slow my site down?

The checks run only when a form is submitted. On a page with a form, one small request fetches fresh hidden-field names; pages without a form make none. Log writes are a single indexed insert, and old entries are cleared on a daily schedule rather than on every write.

Do I need reCAPTCHA as well?

Usually not. The honeypot and time check stop the great majority of automated spam invisibly. reCAPTCHA is there for when you are being targeted specifically.

Does it work with page caching?

Yes. The rotating field names are accepted for three days, so a visitor submitting a page served from cache is not refused. This is the same idea as WordPress honouring the previous nonce tick.

Can I stop it storing personal data?

Yes. Switch off “Store submission details” in Settings and the log keeps only the block reason, the form and the timestamp.

Reviews

There are no reviews for this plugin.

Contributors & Developers

“DadsFam AntiSpam” is open source software. The following people have contributed to this plugin.

Contributors

Translate “DadsFam AntiSpam” into your language.

Interested in development?

Browse the code, check out the SVN repository, or subscribe to the development log by RSS.

Changelog

2.13.3

  • Changed: the AI second opinion now uses the AI Client built into WordPress. You connect an AI service once for your whole site under Settings Connectors (WordPress 7.0 and later) — for example Anthropic, Google or OpenAI — and Anti-Spam uses it. The plugin no longer holds an AI key of its own, and a key saved in it before is removed. Still off by default; nothing changes on a site that never switched it on.
  • Safer database queries. Every query passes its table name through WordPress’s identifier placeholder instead of writing it into the SQL, and the log search runs one fixed query whatever the filters. Needs WordPress 6.2 or later.
  • Clearer about outside services. The readme’s External services section now gives, for each one, what it is, the exact address it uses, whether an account is needed, and what is sent and when.
  • The author link now points at plugins.dadsfam.co.za.

2.13.2

  • Fixed: a browser’s autofill could get a real person turned away. On 10 October a breeder creating a login on a registry site was stopped by the hidden trap field, the field people cannot see and only bots fill in. Browsers and password managers can fill it too, with the person’s own details. The trap is now kept out of their reach, and a trap holding the visitor’s own name, email address, phone number or username is no longer taken for a bot.
  • The hidden trap can no longer turn anyone away on its own on a sign-up or login form. A link in it is still an instant block, because that is a bot. Anything else counts as a strike, and only an address that fills it five times in fifteen minutes is held back. On a message it adds points instead, and the message is judged on everything else, so a real one still arrives or is emailed to you.
  • Signed-in members are never stopped by the hidden trap.
  • The Spam Log shows what was in the trap, so a block like this can be explained.
  • Fixed: comment forms and form plugins carried the trap twice, and the second, empty copy hid what a bot had typed into the first. Now there is one.

2.13.1

  • Fixed: the CAPTCHA “Test” button always asked Google. On a site using Cloudflare Turnstile or hCaptcha it sent your secret key to Google and gave the wrong answer. It now asks the service you chose, and only that one. The self-test does the same.
  • Fixed: Export CSV was hidden, and did not download. The button only appeared with the PRO add-on, and pressing it showed a page of code instead of a file. It now appears for everyone and downloads the Spam Log as a spreadsheet. Anything a visitor typed that a spreadsheet would treat as a formula is saved as plain text.
  • Fixed: some test results never appeared. “Test the saved keys” for the CAPTCHA, the Claude connection test and the settings export and import wrote their answer to the page but kept it hidden, so pressing them seemed to do nothing. The answers now show.
  • Fixed: the Blocklists screen still described old limits. It said the free plugin stops at 100 entries and that IP ranges and wildcards need PRO. Neither is true: every list is unlimited and ranges work for everyone. The screen now says so.
  • Clearer about what leaves your site. Downloading the public spam lists from GitHub no longer sends your site’s address, and the screens now say “no visitor data sent” rather than “nothing sent”. The Claude second opinion now lists everything it sends, including your site’s tagline.
  • Protection Health can reach 100% on the free plugin. It used to stop at 96% unless PRO was installed.
  • Tidied. The hidden spam-trap field and the dashboard chart are escaped as they are printed, the Blocklists screen lost a stray closing tag that pushed its Save button outside the page, the Spam Log says how many entries it keeps (the newest 100,000), and notes about versions before 2.0 were removed from the Changelog screen.

2.13.0

  • Fixed: a CAPTCHA can no longer turn a real person away on its own. A token that never arrived (a privacy blocker, a slow phone, a form shown after the page loaded), an expired one, Google’s “browser-error” and a low v3 score were each a hard block on custom forms — and on one site real puppy enquiries, member sign-ups and a repair request were turned away. On a message the CAPTCHA now only adds points to the spam score. On a checkout, a sign-up or a form plugin, one bad result is a strike, and only an address that collects five in fifteen minutes is held back.
  • Fixed: sign-ups, logins, the cart and the checkout were treated as messages. A long name or a dog’s colours were read as “the message”, so a registration met checks meant for contact forms. Only something written to you now gets the full checks; a sign-up, a login, an add-to-cart button or a signed-in member only meets the honeypot, your blocklists and the public spam lists, and WooCommerce’s cart, checkout and account forms are left to WooCommerce.
  • Fixed: sending the same message twice was blocked. People send one enquiry to two recipients, or again after an error. Only the third identical copy to the same recipient now counts as a repeat.
  • Fixed: the rate limit and the time check applied to every form. Using a members’ portal could lock a member out for an hour, and a login filled in by a password manager was “too fast”. Both now apply only to messages.
  • Fixed: the email check scored your own email template. A site’s HTML email counted as “HTML in the message”, so an enquiry on its way to its recipient and a shop’s “your account has been created” email were stopped. A submission is now judged once, by the words the visitor typed, and store emails are never touched.
  • Fixed: the Brain learned from the wrong evidence. A failed CAPTCHA or a fast submission taught it that the message was spam — real enquiries included. It now only learns from evidence about the message, the self-repair undoes the old lessons on this update, and links to your own site or to Facebook and WhatsApp never become spam fingerprints.
  • Fixed: ordinary writing added points. “I <3 puppies”, “Thanks!!!!!”, a budget in rand and a name typed in capitals no longer count against anyone.
  • Fixed: honest numbers. Visitors the CAPTCHA let through were written to the Spam Log and counted as blocks. They no longer are, and the self-repair removes the old rows.
  • New: never lose a real message. When a check that judges how a message arrived holds one that reads like a real person, it is emailed to you straight away with Reply-To set to the sender, and the visitor is told it arrived. One link in the email lets them straight through next time. At most ten a day, never the same message twice. On by default.
  • New: the Brain can only tip a message the rules already find suspicious, and holds itself back sooner on a small site that has seen few real messages.
  • New: a mistyped email address is told what to fix — “Did you mean @gmail.com?” — instead of being refused without a word.
  • Improved: a new CAPTCHA script that never cancels or re-sends a form. It prepares a token while the visitor fills the form in, asks for one token for the form being used rather than one for every form on the page, leaves search boxes and filters alone, and picks up forms added after the page loaded. It is now a proper script file rather than code printed into the page.
  • Improved: the hidden fields are in place from the first moment, and the server is only asked for fresh ones on pages that have a form to protect.
  • Improved: Claude Sonnet 5.5 for the Claude second opinion. Sites that had chosen Sonnet move to it by themselves.

2.12.3

  • Fixed: with reCAPTCHA v3 on, a form that sends itself could be sent twice. When the page had been open longer than about 100 seconds, the plugin refreshed its token and sent the form for the visitor. It made that choice before the form’s own script had run, so it also took over forms that send themselves (an upload with a progress bar, an AJAX form, a checkout), and they arrived twice. On one site a single tap became two identical registrations. The plugin now decides after every other script on the page, and leaves a form alone when something else is sending it.
  • Fixed: the button a visitor pressed is kept when the plugin re-sends a form. Some forms check which button was pressed, and a re-sent form used to arrive without it.

Older versions are listed in changelog.txt.