Announcing the Magic Pages Open House. Quarterly calls with our team!

Back to blog

How to stop spam signups on your Ghost membership site

Bot signups flooding your Ghost members list and triggering magic-link emails? Here's what actually stops Ghost membership spam in 2026 − and what's just theatre.

· 8 min read

If bots are flooding your Ghost members list with fake signups – or worse, using your site to fire magic-link emails at strangers – the single most effective fix is to make Ghost reject signup requests that don't carry a valid integrity token, then add a thin layer of edge protection on top. That one server-side change does more than any firewall rule, and most Ghost sites ship with it turned off.

Here's the honest version of what works, what doesn't, and why – based on running this across roughly 1,400 Ghost sites.

What Ghost membership spam actually looks like

There are two different problems here. They have different causes and different fixes, so it's worth separating them.

  1. Junk free members. Bots create thousands of fake free members with garbage emails. Mostly random strings, disposable domains, and a surprising number of SMS-to-email gateways like txt.att.net. Ghost itself called this out in its signup-spam-protection changelog. The underlying attack pattern caused a lot of uproar in the community in 2025, but has since calmed down again. The damage is a polluted members list and skewed analytics. Annoying, but mostly cosmetic.
  2. Magic-link bombing (the one that actually hurts). This is the nasty one, and quite recent. First attacks were recorded in the beginning of 2026 and have continued ever since. In June Ghost users reported that the number of requests calmed down again, yet some hosters saw an uptick shortly after. Attackers skip your nice signup form entirely and use API requests directly to Ghost's signup API, over and over, with real people's email addresses. Each request makes your site send a real "confirm your subscription" email to a stranger. You become an unwilling email relay. If you've ever seen a wall of login or signup events in your logs from IPs all over the world, hitting addresses that have nothing to do with your audience, that's the pattern.

The issue with these are that your sending domain's reputation tanks because you're emailing people who never asked for anything, and they mark it as spam. In addition, your email costs climb for messages no real subscriber ever wanted and, in a bad case, your email provider suspends you for abuse (and quite frankly, rightfully so).

Why it's so hard to stop

The endpoint under attack is POST /members/api/send-magic-link (Ghost fetches a companion /members/api/integrity-token first). It's public by design − and it has to be, so real people can subscribe.

Ghost's signup uses double opt-in, which is great for list hygiene: a fake signup never becomes a real member until someone clicks the link in the email.

But the email still gets sent. And some people will ultimately click on the link in there and end up becoming a member.

💡
One likely motive: the spammer isn't after the inbox, they're after the response. Send a magic link to a pile of addresses, then check back which ones became confirmed members. Those are people who click links they didn't ask for − so, great potential phishing victims. Ghost has since tightened the sign-in response so it no longer reveals who confirmed, which pulls the rug out from under exactly this.

Ghost does ship some native rate limiting on this endpoint. But the problem is structural: those limits are keyed on the visitor's IP address. Modern signup-spam comes from thousands of rotating IPs. What the Ghost community saw was everything from Tor exits, residential proxies, and entire datacenter IP ranges. Each request looks like a brand-new visitor and never trips an IP-based limit. The same flaw sinks most DIY "rate limit the endpoint" advice you'll find.

The fix that actually worked: enforce integrity tokens

Ghost already has the right mechanism built in. It just doesn't enforce it by default.

When a real browser loads your signup form, it first fetches an integrity token from /members/api/integrity-token. That token is a short-lived, HMAC-signed value. Essentially an additional step a spammer needs to make − and that additional step is expensive.

The browser then has to include it when it submits the actual signup. A simple script that POSTs straight to the API never does this dance, so it never has a valid token.

The weird part about Ghost: Out of the box, Ghost notices the missing or invalid token, logs a warning, and then processes the request anyway. The token is purely optional, unless you explicitly turn on enforcement.

To do that, add this to the top level of your config.production.json:

{
  "verifyRequestIntegrity": true
}

Or, if you run Ghost in Docker and configure it through environment variables, set the same top-level key:

verifyRequestIntegrity=true

With enforcement on, any signup request that arrives without a valid, unexpired, correctly-signed token gets a 400 Bad Request. Because the token is signed with your site's secret and expires quickly, bots can't forge or reuse them. They'd have to run a full real browser session for every single request, which wrecks the economics of a mass attack.

Here's some background of these economics:

Why CAPTCHAs Still Exist: The Arms Race Between Bots and Providers
Why CAPTCHAs persist despite AI advances — the economics, the arms race, and why no better alternative has replaced them yet.

The point is: there are now two steps involved, instead of one. That doesn't seem like a lot for you, but for a spammer it means that they need to spend twice the compute energy on a request. Slower throughput, more energy involved. It gets unattractive to spam your site.

This is the change that did the heavy lifting for us at Magic Pages. Before we enabled it for all sites, we were writing firewall rules and playing whack-a-mole with IP ranges, browser detection, and other nifty tricks. After we enabled it, the bulk of the flood simply stopped arriving. Within days the attacks stopped.

A practical setup for self-hosters

If you run your own Ghost, here's the order I'd do it in:

  1. Turn on verifyRequestIntegrity. This is 80% of the battle. Restart Ghost and confirm legitimate signups still work (they should – real subscription forms fetch the token automatically).
  2. Add a rate limit on a CDN of your choice on /members/api/send-magic-link and /members/api/integrity-token – something like 10 requests per 10 minutes per IP. It won't stop a distributed attack on its own, but it caps the cheap stuff. For this to work, you need a content delivery network (CDN) that can do IP-based rate limiting. At Magic Pages we use Cloudflare.
  3. Add a firewall (WAF) rule that blocks the obvious non-humans on those two paths: Tor exit nodes (Cloudflare's country code T1), empty user-agents, scripting user-agents (python-requestsaiohttpaxioscurlHeadlessChrome), and traffic from datacenter/hosting networks. Real readers don't subscribe to a newsletter from a server in a datacenter. If you have legitimate use cases where this could matter (e.g. running an investigative blog where people sign up for your newsletter through Tor), allowlist them accordingly.
  4. If you spot recurring domains signing up for your newsletter, use the domain blocklist. It's already built into Ghost and doesn't cost anything.

That combination handles the overwhelming majority of what's out there.

The honest truth: you won't hit zero

I'd rather tell you this straight than sell you a fairy tale. When I looked at a recent month of signup traffic across the Ghost sites, I counted roughly 125,000 hits on the magic-link endpoint. About 80% were automated and turned away before any email went out, split across integrity-token rejections, rate limiting, and WAF blocks.

The remaining slice is mostly real people. But a stubborn tail of it comes from bots sophisticated enough to drive a real headless browser (so they earn a valid integrity token), route through a hosting provider's IP, and stay just under the rate limits. The biggest single offenders, in our data, are a handful of well-engineered spam network, originating from known spam data centers – exactly the kind of place no genuine reader signs up from.

So the last mile is, frankly, ongoing maintenance. We check on a regular basis which patterns we can detect and block them accordingly. We watch which networks the surviving spam comes from, and block those networks. It absolutely is a game of whack-a-mole – but it's a small, slow game of whack-a-mole once the integrity-token wall is up, instead of the firehose you started with.

Or skip all of this

Everything above is doable yourself, and if you self-host, you should do it. But it's a lot of moving parts. A Ghost config flag, a rate-limit rule, a WAF expression you have to keep tuning, and a recurring habit of reading firewall logs. That's a lot to ask of someone whose actual job is writing a newsletter.

On Magic Pages, this is handled for you on every site by default. Integrity-token enforcement is on, the edge rate limits and WAF rules are in place, and – because we host around 1,400 Ghost sites behind one shared setup – when a new spam pattern shows up on one site, we block it for all of them. You inherit the defense from everyone else's attacks without lifting a finger.

If that sounds good, you can start a free trial – and the migration's on us. Just reach out.

Frequently asked questions

How do I stop fake members on Ghost?

Enforce integrity tokens (verifyRequestIntegrity: true in your Ghost config) so signup requests without a valid token are rejected, then add edge rate limiting and a WAF rule on /members/api/send-magic-link. The integrity-token step is the one that matters most.

Does Ghost have built-in spam protection?

Partly. Ghost has a domain blocklist and native IP-based rate limiting. Some managed hosting providers, like Magic Pages, also do some automatic blocking. But the native rate limits use an IP address as key, so distributed attacks from many IPs slip through. The integrity-token mechanism is built in too, but it's just not enforced unless you switch it on.

Bots are using your site's API directly to add strangers' email addresses, making your site send confirmation emails to them. It's a form of email abuse that uses your site as a relay, and it can damage your sender reputation. Integrity-token enforcement stops most of it.

Will spam signups hurt my email deliverability?

Yes – that's the real risk. Sending confirmation emails to people who never asked raises spam complaints and bounces, which lowers your sender reputation and can, in bad cases, get your email account suspended. The members-list clutter is the minor problem; the deliverability damage is the serious one.

Can I add a CAPTCHA to my Ghost signup form?

You can add one to a custom signup form in your theme, but not to Ghost's built-in Portal popup. And it won't stop the worst attacks anyway, because those bypass the form and hit the API directly. CAPTCHA only helps if it's verified server-side at the endpoint.

Is turning on verifyRequestIntegrity safe for real subscribers?

Yes. Your real signup form already fetches and submits the integrity token automatically, so legitimate signups are unaffected. Only requests that skipped the proper flow – i.e. bots – get rejected.

Jannis Fedoruk-Betschki

Written by

Jannis Fedoruk-Betschki

Founder of Magic Pages. I build reliable Ghost hosting, so publishers can focus on what they do best − creating. When I'm not improving the platform, I'm probably helping a customer get their site just right.

You Might Also Like

Our first Open House

We hosted our first Open House. Here's the recording, a recap of everything we showed, our new podcast, and an apology to everyone who got stuck in the waiting room.

5 min read

Ghost, Ghost(Pro), Magic Pages − what's the difference?

"Why am I being asked to create a new Ghost account?" One new customer's confusion turned into the explainer we should've written long ago: what Ghost, the Foundation, Ghost(Pro), and independent hosts each actually are -- and what you do and don't lose by switching.

7 min read

Websites powered by Magic Pages

From personal blogs to growing businesses — published with Ghost®, hosted with care.

Loading showcase sites...

Start Your 14-Day Free Trial

No credit card required