CSRF: requests your users never meant to send
Cross-site request forgery abuses the fact that browsers attach cookies automatically. Another site can make a logged-in visitor's browser submit a form to yours, and the session cookie goes along.
Example
app.use(session({ secret: process.env.SESSION_SECRET }));
app.post("/transfer", isLoggedIn, (req, res) => {
transfer(req.session.userId, req.body.to, req.body.amount);
res.redirect("/account");
});app.use(session({
secret: process.env.SESSION_SECRET,
cookie: { secure: true, httpOnly: true, sameSite: "lax" },
}));
app.use(doubleCsrfProtection); // csrf-csrf, or lusca.csrf()
app.post("/transfer", isLoggedIn, (req, res) => { /* … */ });How it happens
A page on an attacker's site contains a form that posts to https://your-site.com/transfer and submits itself on load. If your session cookie is sent on cross-site requests and the endpoint accepts any request carrying a valid session, the transfer happens. Cookie sessions without CSRF tokens and without SameSite are the classic setup.
How to fix it
Make a cross-site request unable to look like a real one.
- Set SameSite=Lax (or Strict) on session cookies
- Add CSRF tokens to state-changing routes (csrf-csrf, lusca, framework built-ins)
- Never change state on GET requests
- For APIs with token auth in a header, CSRF does not apply — cookies are the issue
How RepoVerse finds it
- ModerateCookie sessions without CSRF protection
Another site can submit forms to state-changing routes on behalf of a logged-in user — the browser attaches the session cookie automatically.
data flow · CWE-352
- LowSession cookie without SameSite
Browsers that do not default to `Lax` will attach the cookie to cross-site form posts, which is what a CSRF attack relies on.
website · CWE-1275
Questions
- Is SameSite=Lax enough to stop CSRF?
- It blocks cross-site POSTs in browsers that support it, which covers most attacks. Tokens are still recommended for older browsers and for flows SameSite does not cover, such as top-level GETs that change state.
- How does RepoVerse detect missing CSRF protection?
- It looks for cookie-based sessions with state-changing routes, no CSRF middleware and no SameSite setting, and lists the affected routes in the finding.
Related
- Secure session cookies: the flags and the login stepSet session cookies safely: Secure, HttpOnly and SameSite flags (CWE-614, CWE-1004), regenerating the session at login against fixation, with Express examples.
- Clickjacking: stolen clicks through an invisible frameHow clickjacking (CWE-1021) hides your page in an invisible frame to steal clicks, and the two headers — CSP frame-ancestors and X-Frame-Options — that prevent it.
- IDOR: changing one number to see someone else's dataHow changing an ID in a URL exposes other users' data (IDOR, BOLA, CWE-639), why a login check is not an ownership check, and how to scope lookups to the session.
Updated 2026-10-11