Blocking Disposable Email by MX Record, Not Domain List
Every service that gives something away at signup eventually meets someone collecting it in bulk. Ours gives new accounts a one-time grant of free credits, and in August 2026 we found 121 accounts that existed only to claim it — roughly 951 free credits burned by addresses that were never going to read a second story.
The interesting part isn't that it happened. It's that our disposable-email blocklist — tens of thousands of domains, auto-updated — had never heard of a single domain they used. This is what we found, and the change that made the next rotation fail.
Why domain blocklists lose this race
The standard defence against disposable email is a list of known throwaway domains. We had a good one: an auto-updated public blacklist of roughly 56,000 domains, plus our own curated set. It is genuinely useful and it catches the casual case.
It also has a structural weakness. A domain is cheap and a list update is not instant, so an operator running a throwaway-mail service can simply register new domains faster than any list can learn them. The twenty domains we pulled out of our own signup table were all invisible to both lists — not because the lists are bad, but because the domains were newer than the lists.
Blocking a domain removes one name. The thing actually serving the mail is still there, waiting to be pointed at the next name.
The tell: many domains, one mail backend
Sorted by signup time, the farmed addresses were spread across a dozen unrelated-looking domains. Resolving their MX records — the DNS entries that name the servers accepting mail for a domain — collapsed them into one fleet:
neplis.com MX -> wallywatts.com / wabblywabble.com hutdot.com MX -> wallywatts.com / wabblywabble.com playboot.com MX -> wallywatts.com / wabblywabble.com joystill.com MX -> wallywatts.com / wabblywabble.com novelv.com MX -> wallywatts.com / wabblywabble.com ... (12 domains, one MX pair) jbsze.net MX -> prd-smtp.10minutemail.com
Twelve throwaway domains, one pair of mail exchangers. And one domain had not bothered to disguise anything at all: its mail was handled by a host belonging to a well-known ten-minute-mail service.
That is the asymmetry worth exploiting. Domains rotate cheaply; mail infrastructure does not. Someone spinning up a new throwaway domain still has to point it at a mail server that accepts and displays anonymous mail, and standing that up is real work. The domain is the disguise. The MX record is the address.
The check, in full
At signup we now do two things with the address, in this order:
- Match the domain against the lists. Synchronous, no network call, catches the well-known providers instantly. We walk the domain label by label, so a deep subdomain of a known provider still matches.
- Resolve the domain's MX records and match the exchange hosts against a list of mail backends we have seen serving throwaway addresses. Same suffix-walk. If either check fires, the signup is refused before anything is written to the database and before any mail is sent.
That is the whole idea. The second check is the durable one: when the fleet registers its next twenty domains, they resolve to the same two exchangers and hit the same wall on day one, with no list update and no deploy from us.
Three rules that keep it from hurting real people
An anti-abuse check that occasionally locks out a paying customer is worse than the abuse it prevents. Three constraints do most of that work:
- Fail open. A DNS timeout, a resolver hiccup or an unknown answer means *allow*, never *block*. Unknown is not the same as disposable, and a real person signing in must never bounce because a nameserver was slow. We cap the lookup at 1.5 seconds and treat anything else as clean.
- Never block privacy aliases. SimpleLogin, addy.io, Firefox Relay and iCloud Hide My Email all look disposable and are not — they forward to a mailbox a real person actually reads. Blocking them punishes exactly the privacy-conscious users you most want. Same call for privacy-focused mail hosts generally: human-looking accounts on a service whose purpose is privacy are not a farm.
- Cache the verdict. A domain's MX records do not flap, so the answer is cached per process. The DNS lookup happens roughly once per domain, not once per signup.
What we deliberately didn't do
- We didn't purge the accounts we found. They had already spent their grant; deleting them would have cost us the record and gained nothing. The gate is about the next 121, not the last.
- We didn't use our email-validation library's all-in-one check. It bundles disposable-domain detection with its own address-format rules, and a formatting quibble must never surface to a user as "we don't accept temporary email addresses". We call the disposable check alone and let format validation fail with its own message.
- We didn't add a CAPTCHA. The cost here was one-time free credits, not compute. Adding friction to every honest signup to slow a hundred-odd fake ones is a bad trade.
Honest limits
This is a speed bump, not a wall, and it is worth being precise about where it stops:
- A throwaway provider whose backend we have never seen passes until we see it. The check learns from observation; it does not predict.
- Because it fails open, anyone who can make DNS resolution fail can get through. That is a deliberate trade: we would rather admit a farmer than reject a customer.
- It does nothing about the harder version of the problem — real mailboxes, bought in bulk, with working MX records at ordinary providers. Nothing at the email layer will.
What it does buy is time, and it buys it in the right currency: the defender updates a short list of mail backends, while the attacker has to stand up new mail infrastructure. Most of the time that asymmetry is on the wrong side. Here it isn't.
If you are looking at your own signup table for the first time, start there — resolve the MX records for every domain that appears more than once and sort by exchanger. The clusters tend to be obvious. What we collect at signup and why is on our privacy page.
FAQ
What is a disposable email address?
A temporary, throwaway mailbox — often anonymous and public — that a service hands out for minutes or hours so you can receive one confirmation message without giving out a real address. They're used legitimately to avoid spam, and abusively to farm signup rewards in bulk.
Why check MX records instead of the domain?
Domains are cheap and rotate faster than any blocklist updates, but the mail server behind them rarely changes. Matching the MX exchange host catches every future domain pointed at a backend you've already seen, without a list update.
Doesn't this block privacy services like SimpleLogin or Firefox Relay?
It shouldn't, and ours doesn't. Aliasing services forward to a mailbox a real person reads, so they belong on the allow side. Treating them as disposable penalises privacy-conscious users, who are rarely the ones farming free credits.
What happens if the DNS lookup fails?
The signup is allowed. Failing open is the only safe default — an unknown answer is not evidence of abuse, and a real user must never be locked out because a resolver was slow. We time the lookup out at 1.5 seconds.
Does this stop signup abuse completely?
No. It stops throwaway providers whose mail backend has been observed once. Bulk-bought real mailboxes at ordinary providers pass straight through it, and no email-layer check will catch those.
Written by the team behind SinStories
We run an 18+ AI story service — the free signup credits described above are exactly what the farm was after. If that's what brought you here, the generator is on the home page.
Generate story