Ghost subscribe form hit by spam signups, hurting sender reputation

Today my blog started getting hit by a sudden burst of spam email signup attempts:

It looks like potentially someone is trying to validate a stolen or bought list, and then the owners of the email addresses that work are marking the confirmation emails (which they did not ask for) as spam. (At least, I can’t think of any other plausible way this would benefit the attacker.)

If possible, I would like to avoid hiding behind Cloudflare. I’m self-hosting on Fly.io, and using Postmark for transactional email, and Mailgun for newsletters.

I see in my logs POST //members/api/send-magic-link" 201, and my hunch is that someone is hitting the endpoint directly with a script.

I found promising solutions by @HauntedThemes:

SELECT * FROM subscribers WHERE subscribed_url != ‘’;
DELETE * FROM subscribers WHERE subscribed_url = ‘’;

And @dlford:

ALTER TABLE subscribers MODIFY subscribed_url varchar(2000) NOT NULL;

However, the Ghost DB schema has changed since then, and I’m not sure if these sorts of approaches are still recommended.

What mitigation would you recommended?

Thanks!

For anyone else with the same problem:

I ended up capitulating and putting my blog behind Cloudflare, but even with bot fight mode activated, it didn’t help. However, a quick look in the actual logs showed that it was a very basic script kiddie attack, and even though the IPs seemed to change (mostly US and UK so far), they hadn’t bothered to spoof the user agent:

"user-agent":"Python/3.12 aiohttp/3.9.5"

So I added a Cloudflare Web Application Firewall (WAF) custom rule to block requests to /api/send-magic-link when the user agent “contains” Python and aiohttp.

I’m still looking for a better solution, that I can implement at the Ghost or Fly.io level, without relying on Cloudflare.

1 Like