Possible Spam Signup Remedy

Hi all,

I‘ve been following the various threads about how to prevent spammers from signing up random emails for whatever reasons. It happens to my super small self-hosted blog as well. Obviously, I don’t want people to receive unwanted signup emails and possibly declaring them as spam which can hurt my sender’s reputation.

My idea was to set a custom header that nginx verifies when /members/api/send-magic-link/ is hit. So I added this code to Settings→Advanced→Code Injection→Header:

<script>
const originalFetch = window.fetch;
window.fetch = function() {
    if (typeof arguments[0] === 'string' && arguments[0].includes('/members/api/send-magic-link/')) {
        arguments[1] = arguments[1] || {};
        arguments[1].headers = {
            ...arguments[1].headers,
            'X-Ghost-Human': 'true'
        };
    }
    return originalFetch.apply(this, arguments);
};
</script>

Then I added to my nginx.conf:

location /members/api/send-magic-link/ {
                    if ($http_x_ghost_human != "true") {
                        return 403;
                }

                proxy_pass http://127.0.0.1:2368;

                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;

                include proxy_params;
        }

Tested it with:

curl -X POST https://mysite.com/members/api/send-magic-link/ -I
HTTP/2 403 
server: nginx
date: Tue, 14 Apr 2026 06:54:40 GMT
content-type: text/html
content-length: 146

Works. I tried signing myself up with a new email and it worked as well. Let’s hope the spammers won’t read here..

8 Likes

I’m afraid some of the latest spam signups are using OpenClaw with a real browser and real email so they might pass this human test.

I’m seeing new spam signups almost every day now. I suspect later they want to use the accounts for comment spam.

You’re right, my method doesn’t help against headless browsers. However, I’m seeing 5-10 potential spammers who get the 403 error when hitting the send-magic-link directly.

With that said, I still don’t understand why the Ghost team doesn’t add a few Captcha options.

Thank you for this, I’ll have to try it out soon. Spam signups have been getting really annoying recently. I don’t want random people to receive a welcome message and subsequently think I’m spamming them. Though I’m still puzzled what the final goal is, as my site doesn’t even offer comment functionality.

1 Like

Lots of speculation what the use for these spam signups is but my workaround is still keeping them away. Hope it works for you as well.

1 Like

Giving this a shot as I’ve been getting a TON of spam signups. Wild that Ghost cant put some sort of challenge in front of this. I also added cloudflare managed challenge on the signup though not yet sure how much that will help.

combined with a fail2ban rule on 4xx this should be pretty interesting

Good luck! Hope it works out for you. The spammers never used the same IP more than once in my logs so not sure how much Fail2ban helps here.

This is a worthy mod to add to the arsenal, caught 7 attempts yesterday. Well done. I did modify the code slightly so its not exactly like how youve posted here so that if they mirror your solution it wont work.

1 Like

I think this method will break “Signup forms” (Settings → Growth → Signup forms). If you use them, it’s worth checking.

2 Likes

yeah, just tested, youre correct. I dont use them though so not a concern for me. good for anyone else to be aware of though. all the more reason for a proper solution from the ghost development team.

1 Like

For comment spam, they need access to all those emails to be able to “sign in”, right? I don’t think that’s the case.

Thanks for pointing this out! It should still be possible to put the code snippet that sets the x-ghost-human header in front of the code for the form. Alternatively, let the IP address of the webserver with the signup form pass through in the nginx.conf part where it checks for the x-ghost-human header.

I’ve been getting bombarded with fake sign-ups for the last few days on my mostly-inactive blog. This morning they were coming in every few minutes, non-stop…

Did the code injection as shown at the top of this thread. Since I use a Cloudflare Tunnel for my site, I created a Security Rule in Cloudflare instead of the nginx.conf to block the bots.

Nine bots attempts blocked in the first hour. I’ll call that a win.

EDIT: Now up to 41 bot attempts blocked in just under 24hrs, from IPs all over the world. A majority seem to come from “Green Floid LLC” in the U.S., “M247” in Europe, and “The Constant Company LLC” in Canada & Europe. And an occasional consumer ISP IP sprinkled in there. I wonder what this apparent botnet hopes to accomplish.

3 Likes