If you've been following along, you know I spend an unreasonable amount of time thinking about infrastructure. This post is about a problem I've been really really annoyed with for the last couple of days – and an experiment I'm running to solve it.
The Spam Problem
Ghost has this feature called magic links. Passwordless authentication that sends a login link to your email. It's convenient for users wanting to sign up for your newsletter. It's also, apparently, convenient for spammers.
Over the past weeks, many Ghost admins have seen spam attacks targeting the magic link endpoint across Ghost sites. The attack pattern is frustrating: requests are routed through Tor exit nodes (so, rotating IPs) to slowly and steadily use the endpoint to trigger unwanted emails. Traditional IP-based rate limiting doesn't help much when every request comes from a different address – and the requests are so infrequent that rate limiting won't do much good.
Murat from Synaps Media has written about it in more detail on the Ghost forum:

The solution is a WAF (Web Application Firewall) that can apply smarter rules. It can challenge suspicious traffic, block known bad actors, and detect abuse patterns. And critically for me, it needs to work across all Magic Pages sites at once.
The Search
I spent the last few days talking to CDN providers about WAF options. The conversations were...educational. Pricing for WAF protection at Magic Pages's scale ranged from "ehh okay" to "you want how much per month????"
Per-zone pricing models – where you pay for each customer site separately – don't scale well for a hosting platform. What works for a freelancer with a handful of customer sites becomes absurd at 1,000+.
Unfortunately, that's exactly the pricing model my go-to CDN provider, Bunny.net, is applying for their WAF-product called "Shield".
I am already using their free version on every single Magic Pages site – but the free version does not allow custom rules and is rather targeted at Wordpress-powered sites, it feels.
Their advanced tier well...let's just say I'd have to increase Magic Pages's pricing to justify that.
Cloudflare for SaaS
I'd heard of Cloudflare for SaaS before but assumed it was enterprise-only. Turns out it's not. It's designed for exactly the use case I had in mind: a platform serving traffic for many customer domains through shared infrastructure.
The way it works:
- You set up a Cloudflare zone as your "SaaS zone"
- Customers CNAME their domains to you (same as on Bunny.net)
- All traffic flows through Cloudflare's network
- WAF rules on your zone apply to all customer traffic
The key difference is that Bunny.net is built on the concept of having one zone per customer site, whereas Cloudflare for SaaS wants one zone per origin.
Therefore, I only have to set up my WAF rules ones – and they get applied to all customer sites connected to the zone. Beautiful.
Additionally, Cloudflare represents Tor exit nodes as country code T1. So the WAF rule is literally just "if the path contains /members/api/send-magic-link and the country is T1, challenge the request." Done.
Setting this up and testing it (e.g. simulating the attack myself) took me about half a day. Not bad, considering it literally turns my infrastructure upside down.
The Experiment
Right now, this blog – jannis.io – is running through Cloudflare for SaaS, rather than the usual Bunny.net pullzone. It's the guinea pig (as always 🙃).
If you're reading this and something feels off – slower page loads mainly – I want to know. Seriously. The whole point of testing on my own site first is to catch issues before they affect anyone else.
So far, so good. Performance in my testing has been solid (about 40-50% faster than Bunny.net), cache invalidation is working, and the WAF rules are doing their thing. But there's only so much you can learn from lab tests and curl commands.
What's Next
If this experiment goes well, I'll start migrating Magic Pages sites gradually. The goal is proper WAF protection across the platform without sacrificing the performance you're used to.
