I wrote a post a while back about Server Actions being public, directly callable endpoints regardless of your UI, and a fair number of comments pushed back with some version of "sure, but at least they're not vulnerable to CSRF like a regular form post would be." That pushback is actually correct, and it's worth explaining exactly why, because the same protection does not automatically extend to a plain API route handler doing the same job.

What CSRF Actually Is, Quickly

Cross-Site Request Forgery is when a malicious site gets a victim's browser to send a request to your app, riding on the victim's existing authenticated session cookie, without the victim knowing it happened. If your app trusts any authenticated request regardless of where it originated from, a malicious site can trigger real actions, transferring funds, changing account settings, on behalf of a logged-in user who never intended to do any of it.

Why Server Actions Are Actually Safer Here by Default

Next.js automatically checks the Origin header on every Server Action invocation and compares it against your app's own host. A request claiming to be a Server Action call, but arriving with an Origin header that doesn't match your deployed domain, gets rejected automatically, before your action's own code even runs.