Blog
CSRF in 2025: Not Dead, Just Different
·
Tuesday, August 19, 2025

Brad Geesaman
Principal Security
How to stop Cross-Site Request Forgery before it silently hijacks your app
Cross-Site Request Forgery (CSRF) isn’t flashy. It doesn’t crash your servers or leave a trail of obvious damage. But it does let attackers quietly trick your users into doing things they never intended — like resetting a password, draining an account, or making unauthorized changes to sensitive data.
And while modern web frameworks have better defenses baked in, CSRF is still very much alive in 2025, especially in custom APIs, microservices, and single-page apps where devs rely on cookies for auth but forget to implement cross-site protection.
Let’s break it down.
What is CSRF?
CSRF happens when a malicious site causes a logged-in user’s browser to send unintended requests to another app where they’re authenticated. Because browsers send cookies automatically, these requests look legit to the receiving server — even though the user never actually intended to make them.
Picture this:
A user is logged into
bank.com
.They visit a malicious site with this embedded:
The browser sends a GET request to
bank.com
— including the user’s session cookie.If
bank.com
doesn’t check for CSRF, the money gets transferred.
Silent. Brutal. No clicking required.
Why CSRF is still a problem
You might be thinking: "Don’t browsers block that now?" Kind of. Modern protections like SameSite cookies help, but they’re not a silver bullet:
SameSite misconfigs are surprisingly common.
Legacy browsers still exist.
Many teams still rely on manual CSRF tokens… and forget to add them in key places.
Devs often skip CSRF protection on internal tools or “harmless” endpoints like preferences, avatars, etc. That’s exactly where attackers start.
In other words: CSRF has evolved. So should your defenses.
Real-world CSRF attack examples
Reddit (2023): A CSRF vulnerability in a settings page let attackers silently toggle notification preferences and link spammy accounts to user profiles.
Crypto wallet apps: Attackers used CSRF to silently change default send addresses or drain small amounts by piggybacking on logged-in sessions.
Microservices gone wild: Internal admin tools (often assumed “safe”) lack token checks or assume API calls from frontend apps can be trusted.
Even with SameSite=Lax by default, many endpoints still allow side-effect-inducing GETs or improperly scoped POSTs. If you're not checking for intent, you're assuming a lot — and that's where CSRF slips in.
How to prevent CSRF
Here’s what actually works in 2025:
Use SameSite cookies — correctly
Set your session cookies to:
SameSite=Strict
blocks most cross-origin requests entirely.SameSite=Lax
is a solid default — it still allows top-level GETs (e.g., from clicking a link), but blocks auto-submitted POSTs.Be careful: if your app needs third-party embeds or cross-origin requests (e.g., for OAuth), configure these explicitly and isolate them from your main auth cookies.
Require CSRF tokens
Still the gold standard. Here’s how it works:
Server generates a unique token and embeds it in the HTML form.
Token is submitted along with the request.
Server checks that the token is valid and matches the user’s session.
Use double-submit cookies or synchronizer tokens, and rotate tokens frequently. Bonus points if you check the Refererand Origin headers too — they can catch suspicious cross-origin attempts.
Don’t allow state-changing GETs
This is a classic dev mistake. “It’s just a quick link that triggers an action…” — and that’s exactly what CSRF loves.
If an endpoint performs any of the following:
Changes user data
Alters a setting
Initiates a transaction
…it needs to be POST or PUT — never GET — and protected by CSRF tokens.
Lock down internal tools and microservices
Too often, internal endpoints rely on frontend enforcement, like:
But if the backend doesn’t also check authentication and CSRF tokens, attackers can forge requests with insider-level privileges — no credentials needed.
Ghost’s Advantage: Find CSRF Flaws at the Source
It’s easy to miss CSRF protections when you’re deep in dev mode. Frameworks handle some of it, but one misconfigured SameSite cookie or an unprotected endpoint is all it takes.
Ghost scans your repo and automatically identifies:
Endpoints that mutate state but lack CSRF tokens
Missing or misconfigured SameSite attributes
Unsafe GETs or publicly exposed admin routes
REST calls across microservices where token checks are missing
And since Ghost’s AI understands application flow, it won’t flood you with false positives. You’ll only see what actually matters — with remediation suggestions and even fix-ready pull requests in some cases.
Want to see what Ghost finds in your app?
You can scan one repo for free and get a detailed report.