How to stop fake signups
Also called: bot signups · fake account registration · spam registrations · bulk account creation
What it costs you
- trending_downYour email deliverability, which is the expensive one. Fake addresses bounce, spam traps get hit, and your mail stops arriving for real customers too.
- trending_downEvery number you make decisions with. Signup conversion, activation, retention, and the cost-per-customer you report to whoever funds you.
- trending_downInfrastructure you are paying for on behalf of nobody, plus any per-user fee your own vendors charge you.
- trending_downSupport and moderation time, which grows with account count rather than revenue.
- trending_downYour database as an asset. Once real and fake are mixed together, you cannot cleanly pull them apart later without guessing.
How the attack runs
- 01
Find a form that costs nothing to submit
Bulk registration is only worth automating when an account is free, instant, and useful the second it exists. Anything that delays usefulness (a confirmation email that really does gate access, manual approval, a payment) changes the maths before any detection does.
- 02
Automate the submission
At the cheap end, a script posts straight to your registration endpoint and never touches your front end. At the expensive end, a real browser is driven by software, which behaves much more like a person because mechanically it is one.
- 03
Supply emails in bulk
Made-up addresses on a domain they own, throwaway providers, or addresses from a breach list. The addresses are usually perfectly well formed, because generating valid-looking email is trivial.
- 04
Spread out where it comes from
Data centre addresses first, because they are cheap. Residential proxies once data centre stops working. The same signups then arrive from thousands of ordinary-looking home connections.
- 05
Use the accounts, or do not
The step people forget. A large share of fake signups never do anything at all. They exist to be sold later, to age until they look established, to plant 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, so a serious operator treats a CAPTCHA as a cost of a fraction of a cent per account. Meanwhile it measurably lowers completion for real users, worst of all for people using screen readers or on slow connections. It raises the floor slightly and taxes your real signups forever.
Email confirmation before the account works
Genuinely useful, and easily beaten by anyone using a domain they control or a throwaway inbox with a web page. It also costs you real customers, because a real share of legitimate users never come back from their inbox.
Blocking known data centre ranges
Catches the first, cheapest wave and nothing after it. The answer is a residential proxy, which costs a little more and looks exactly like a customer's home broadband.
Rate limiting by IP
Necessary and not enough. It stops one address making a thousand attempts, which is not how anyone does this after week one, and it will eventually throttle a university or an entire mobile carrier.
Deleting the obvious ones later
The damage mostly happens at creation, not at use. The bounce already hurt your sending reputation and the account already polluted the numbers you reported. 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.
Signs of a script in the session
Kaidn checks thisHeadless and software-driven browsers leak. Browser properties that contradict the graphics stack, missing or inconsistent APIs, and timing no hand produces. This is what separates a script from a person, and it does not depend on knowing anything about the identity.
How long the form took to fill
you build thisPeople read labels, tab between fields, make corrections and pause. Scripts submit a complete, correct form 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 scale.
How old the email domain is and where its mail lives
Kaidn checks thisA domain registered last week with no mail history, or one that accepts absolutely any address, is a very different thing from a fifteen-year-old provider. This still works when the address itself looks completely ordinary.
When the signups arrive
Kaidn checks thisReal registrations follow the working day and your marketing calendar. Automated ones arrive in flat bursts, often while your real users are asleep, and stop the instant they hit a rate limit.
Which networks they come from
Kaidn checks thisEven across thousands of home addresses, abuse clumps in particular networks. You can only measure that clumping across traffic over time, which is exactly what a single 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. It is not, because it means the reward you think you are protecting is often not what is driving the attack.
Accounts get created to be sold later, to age until they look established, to plant 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 with one name#
Worth separating, because the defences are different.
Automated bulk registration is a machine problem. Thousands of accounts, nobody at the keyboard, and the giveaway is in how the session behaves rather than what it claims to be. This one responds well to automation detection.
Fake signups made by hand are somebody genuinely sitting there creating accounts, usually because there is money at the end. Every automation signal comes back clean, because there is no automation. That is bonus abuse, and it needs signals about how accounts connect to each other, not bot detection.
Most teams buy a defence for one and are surprised when the other carries on.
The first cost you feel is email#
If you take one practical thing from this page, take this. The damage to your email arrives before anything else, and it is the hardest to undo.
Send a welcome email to a few thousand made-up addresses and you will get hard bounces and, worse, spam traps. Mailbox providers read that as a sender who does not know who their recipients are, and the penalty then applies to every message you send afterwards, including the ones your paying customers are waiting for.
That is why "we will clean them up later" fails. The reputation hit already happened, the moment you first mailed the list.
Make a new account worth less on day one#
The most effective change here is usually not a detection one. It is moving the value of an account away from the second it exists.
If a new account can immediately send messages, plant links, burn API quota or show up in a public directory, bulk creation is worth automating. If those things unlock after some real usage, or after a first payment, the same attack produces thousands of accounts that are useless to the attacker, and the economics quietly stop working.
Detection then mops up what is left, instead of carrying the whole load.
Where we sit#
We score the registration: signs of a script in the browser, form timing, the email and the domain behind it, IP and network reputation, and how fast the same pattern is repeating across your traffic. You get back allow, review or block, with the checks that fired and what each one counted for, so you set the line yourself rather than accepting somebody else's.
We are not a CAPTCHA and we never interrupt the user. If you want a product that stops the person in the form, that is a different tool and it is reasonable to run both.
Scoring the registration#
The call, 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 | this is a headless browser build |
device_tampered | deviceIntegrity | the parts we fingerprint have been patched |
engine_ua_mismatch | deviceIntegrity | the real JavaScript engine contradicts the browser it claims to be |
os_mismatch | deviceIntegrity | something that reveals the real OS contradicts what was claimed |
mx_on_hosting | emailRisk | the domain's mail runs on generic hosting, not a mail provider |
mx_temp_mail_software | emailRisk | the mail server is running known throwaway-mail software |
ip_velocity | velocity | this address is moving through the funnel too fast |
abusive_asn | ipRisk | this network shows up in abuse far more than its share of traffic |
Collect the device signal at submit, and fail open#
The browser half is one import and one call, made when they act rather than on every page load.
The catch is not optional. A blocked script, an ad blocker or a flaky connection 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 chart how long each one took to fill in the form.
If there is a spike under two seconds, you have automation, and you now know what share of your signups it is. That costs nothing, 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 a defence aimed at one misses the other. A bot registration is a script filling your form, usually at volume, usually to farm something. A fabricated human registration is a real person creating an account with details that are not theirs. 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 farm run by actual people never meets the problem at all, because there is a person. 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 feel?
Because made-up addresses bounce, and your 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 real users as mail that stops arriving. It is the loss teams notice last and pay for first.
Which signals separate a scripted signup from a real one?
Signs of a script in the session (headless_browser, device_tampered, emulated_environment, engine_ua_mismatch, os_mismatch), the mail setup behind the email domain (mx_on_hosting, mx_temp_mail_software, abusive_email_domain), how fast they are arriving, and which networks they cluster on. How long the form took to fill is a strong fifth signal that Kaidn does not collect.
Should I block a signup outright?
Rarely, and never on one signal. The cheapest right answer is usually to let the account exist and make it worth less: hold the bonus, hold the trial, require verification before anything valuable is issued. A blocked registration that turns out to be 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.