How to stop fake signups
Also called: bot signups · fake account registration · spam registrations · bulk account creation
What it costs you
- trending_downYour sender reputation, which is the expensive one. Fake addresses bounce, spam traps get hit, and your deliverability falls for every real customer too.
- trending_downEvery metric you make decisions with: signup conversion, activation, retention cohorts, and the CAC you report to whoever funds you.
- trending_downInfrastructure you are paying for on behalf of nobody, plus any per-seat or per-user cost your own vendors charge you.
- trending_downSupport and moderation time, which scales with account count rather than revenue.
- trending_downYour database as an asset, because once real and fake are mixed you cannot cleanly separate them later without guessing.
How the attack runs
- 01
Find a form with no meaningful cost
Bulk registration is only worth automating when an account is free, instant, and useful the moment it exists. Anything that delays usefulness (email confirmation that actually gates access, manual approval, a payment step) changes the arithmetic before any detection does.
- 02
Automate the submission
At the cheap end this is a script posting directly to your registration endpoint, skipping your front end entirely. At the expensive end it is a real browser driven programmatically, which behaves much more like a person because it is one, mechanically speaking.
- 03
Supply identities in bulk
Generated local parts on a domain the operator controls, disposable providers, or addresses from a breach list. The addresses are usually syntactically perfect, because generating valid-looking email is trivial.
- 04
Spread the source
Datacenter ranges first, because they are cheap, and residential proxy networks once datacenter stops working. The same account creation then arrives from thousands of ordinary-looking consumer connections.
- 05
Use the accounts, or do not
This is the step people forget. A large share of fake signups never do anything. They exist to be sold later, to age before use, to place a link, or because your form was simply on a list somebody was working through.
What does not work
These are the defences most teams try first. They are listed here because trying them and watching them fail is expensive.
A CAPTCHA on the form
Solving services are cheap and fast, and a determined operator treats a CAPTCHA as a per-account cost of a fraction of a cent. Meanwhile it measurably reduces completion for real users, and disproportionately for people using screen readers or on poor connections. It raises the floor slightly and taxes your genuine signups permanently.
Email confirmation before the account works
Genuinely useful, and defeated by anyone using a domain they control or a disposable inbox with a web view. It also costs you real conversions, because a meaningful share of legitimate users never come back from their inbox.
Blocking known datacenter ranges
Catches the first, cheapest wave and nothing after it. The response is a residential proxy, which costs the operator a little more and looks exactly like a customer's home broadband.
Rate limiting by IP
Necessary and insufficient. It stops one address making a thousand attempts, which is not how anybody does this after the first week, and it will eventually throttle a university or a mobile carrier's entire NAT pool.
Deleting the obviously fake ones later
The damage is largely done at creation, not at use: the bounce already hurt your sender reputation and the account already polluted the cohort you reported on. Cleanup is bookkeeping, not defence.
The signals that do
These are the signals that carry weight on fake signups, and why each one is the signal rather than the obvious alternative. Not all of them are ours: the ones marked you build this genuinely work and Kaidn does not check them, so you would be wiring them up yourself. Listing those unlabelled would read as a claim we cannot support.
Automation tells in the session itself
Kaidn checks thisHeadless and driver-controlled browsers leak: navigator properties that do not match the rendering stack, missing or inconsistent APIs, and timing that no hand produces. This is the signal that separates a script from a person, and it does not depend on knowing anything about the identity.
Form interaction timing
you build thisHumans read labels, tab between fields, make corrections and pause. Scripts submit complete, correct forms in a few hundred milliseconds. Time-to-submit is one of the cheapest signals to collect and one of the hardest to fake convincingly at volume.
Email domain age and infrastructure
Kaidn checks thisA domain registered last week with no mail history behind it, or a catch-all accepting anything at all, is a different proposition from a fifteen-year-old provider. This survives when the address itself looks perfectly ordinary.
Arrival distribution
Kaidn checks thisOrganic registration follows the working day and the marketing calendar. Automated registration arrives in flat bursts, often at hours your real users are asleep, and stops the moment a rate limit is hit.
ASN concentration
Kaidn checks thisEven across thousands of residential addresses, the abuse concentrates in particular autonomous systems. That concentration is only measurable across traffic over time, which is precisely what a per-request lookup cannot see.
The useful thing to understand about fake signups is that most of them are not trying to take anything from you. That sounds like good news and it is not, because it means the incentive you think you are protecting is often not the incentive driving the attack.
Accounts get created to be sold later, to age until they look established, to place a link, to sit in a list somebody bought, or simply because a script was working through a range of targets and your form answered. Removing the reward does nothing to any of that.
Two different problems wearing one name#
It is worth separating them, because the defences differ.
Automated bulk registration is a machine problem. Thousands of accounts, no human at the keyboard, and the giveaway is in how the session behaves rather than what it claims to be. This is the one that responds well to automation detection.
Human-driven fake registration is somebody genuinely sitting there, creating accounts by hand, usually because there is money at the end of it. Every automation signal comes back clean, because there is no automation. That is bonus abuse and it needs relationship signals, not bot detection.
Most teams buy a defence for one and are surprised when the other continues.
The cost you will feel first is email#
If you take one practical thing from this page: the deliverability damage arrives before anything else, and it is the hardest to undo.
Send a welcome email to a few thousand generated addresses and you will hit hard bounces and, worse, spam traps. Mailbox providers read that as a sender who does not know who their recipients are, and the penalty applies to every message you send afterwards, including the ones your paying customers are waiting for.
This is why "we will clean them up later" fails as a strategy. The reputational hit already happened, at the moment you first mailed the list.
Make the account worth less at the moment it is created#
The most effective structural change is usually not a detection one. It is to move the value of an account away from the instant it exists.
If a new account can immediately send messages, place links, consume API quota or appear in a public directory, bulk creation is worth automating. If those capabilities unlock after some real usage, or after a first payment, then the same attack produces thousands of accounts that do nothing useful for the attacker, and the economics quietly stop working.
Detection then handles the residue rather than carrying the whole load.
Where we sit#
We score the registration event: automation traits from the browser, form timing, email identity and domain infrastructure, IP and ASN reputation, and velocity across your traffic. The response is allow, review or block with the checks that fired and their weights, so you can set the line yourself rather than accept somebody else's.
We are not a CAPTCHA and we do not challenge the user. If you want a product that interrupts the person in the form, that is a different tool and reasonable to run alongside.
Scoring the registration#
The event, and the reasons worth branching on:
const r = await kaidn.score({ event: "signup", user_id: user.id, ip: req.ip, email: user.email, device_id: body.kaidn_device_id, timezone: body.kaidn_timezone, // checked against the IP country server-side }); // automation is the one class worth refusing outright: there is no user to lose const automated = ["headless_browser", "emulated_environment", "engine_ua_mismatch", "os_mismatch"] .some((code) => r.reasons.includes(code)); if (automated) return Response.json({ error: "unsupported client" }, { status: 403 }); // everything else: create the account, withhold what it is worth if (r.verdict !== "allow") return createAccountUnverified(user, r.event_id); return createAccount(user);
| reason | check | what it is saying |
|---|---|---|
headless_browser | deviceIntegrity | the session is a headless browser build |
device_tampered | deviceIntegrity | fingerprinting surfaces have been patched |
engine_ua_mismatch | deviceIntegrity | the real JS engine contradicts the browser claimed |
os_mismatch | deviceIntegrity | an OS-truth signal contradicts the user agent |
mx_on_hosting | emailRisk | the domain's mail is on generic hosting, not a mail provider |
mx_temp_mail_software | emailRisk | the MX runs known temporary-mail software |
ip_velocity | velocity | this address is moving through the funnel too fast |
abusive_asn | ipRisk | this autonomous system is over-represented in abuse |
Collect the device signal at submit, and fail open#
The browser half is one import and one call, made at the moment they act rather than on every page
load. The catch is not optional: a blocked script, an ad blocker or an offline visitor must never
stop somebody signing up.
import { beacon } from "@kaidn/fp"; form.addEventListener("submit", async (e) => { e.preventDefault(); let deviceId = null; try { // fingerprints the browser AND beacons it to the edge, ~200ms const fp = await beacon("https://api.kaidn.io/v1/fp", PUBLISHABLE_KEY); deviceId = fp.device_id; } catch { // FAIL OPEN. Your server scores the event either way, with one signal fewer. } await fetch("/api/signup", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ email: form.email.value, kaidn_device_id: deviceId }), }); });
Something to measure before you buy anything#
Take last month's signups and plot time-to-submit on the registration form. If there is a spike under two seconds, you have automation and you now know its share. That is free, takes an hour, and tells you which of the two problems above you actually have.
Frequently asked questions
What is a fake signup, exactly?
Two different things share the name, which is why defences aimed at one miss the other. A bot registration is an automated script filling your form, usually at volume and usually to farm something. A fabricated human registration is a real person creating an account with details that are not theirs or not real. Automation detection catches the first and does nothing about the second.
Will a CAPTCHA stop fake signups?
It stops the cheapest automation and raises the cost of the rest. Solving services price a CAPTCHA in fractions of a cent, and a human-operated farm never encounters the problem at all, because there is a human. Treat a challenge as friction that prices out the laziest attacker, not as a control, and do not let it be the only thing between your form and a script.
Why is email deliverability the first cost I will feel?
Because fabricated addresses bounce, and bounce rate is what mailbox providers read as a signal about you. A few thousand invalid registrations will damage your sending reputation before they damage anything else, and the damage lands on your genuine users in the form of mail that stops arriving. It is the loss teams notice last and pay for first.
Which signals actually separate a scripted signup from a real one?
Automation and integrity tells in the session (headless_browser, device_tampered, emulated_environment, engine_ua_mismatch, os_mismatch), the email infrastructure behind the address (mx_on_hosting, mx_temp_mail_software, abusive_email_domain), arrival velocity, and ASN concentration. Behavioural timing on the form is a strong fifth signal that Kaidn does not collect.
Should I block a signup outright?
Rarely, and never on one signal. The cheapest correct response is usually to let the account exist and make it worth less: withhold the bonus, hold the trial, require verification before anything of value is issued. A blocked registration that was real costs you a customer; a throttled one that was fake costs the attacker time.
Score your own traffic for this
10,000 events a month free, no card. Every verdict comes back with the checks that fired and their weights, so you can see which signal caught it rather than trusting a number.