Login form has CSRF protection
Why it matters
Login CSRF (CAPEC-62) lets an attacker log a victim into an attacker-controlled account using a forged cross-site request. This enables account takeover indirectly: the victim, now logged into the attacker's account, may enter sensitive data that the attacker can later retrieve. CWE-352 (CSRF) on a login endpoint is classified under OWASP A01 (Broken Access Control); PCI-DSS v4.0 Req-6.2.4 explicitly lists cross-site request forgery among the software attacks that engineering practices must prevent. SameSite=Lax provides meaningful browser-enforced protection for most cases, but explicit CSRF token validation is required for custom endpoints that process sensitive actions on navigation.
Severity rationale
Critical because login CSRF can silently associate a victim's activity with an attacker's account, enabling credential harvesting and session theft without any direct compromise of the victim's credentials.
Remediation
If using NextAuth, CSRF protection is built into the credential callback — do not bypass the standard signin form flow. For custom endpoints, add explicit CSRF token validation:
import { csrf } from '@edge-csrf/nextjs'
const csrfProtect = csrf({ cookie: { secure: true } })
export async function POST(request: Request) {
const csrfError = await csrfProtect(request)
if (csrfError) return Response.json({ error: 'Invalid CSRF token' }, { status: 403 })
// login logic
}
Verify session cookies have SameSite=Lax set (see the session-tokens-secure check) as a defense-in-depth layer. Do not rely on SameSite alone when you can add a CSRF token.
Detection
-
ID:
login-csrf -
Severity:
critical -
What to look for: Examine the login endpoint for CSRF protection. In NextAuth: CSRF protection is built-in via the
csrfTokenmechanism — verify the login form uses the/api/auth/csrfendpoint to retrieve the token. In custom endpoints: check for CSRF token validation middleware,SameSite=StrictorSameSite=Laxcookie enforcement, orOrigin/Refererheader validation. For cookie-based sessions,SameSite=Laxprovides meaningful protection for top-level navigations. Count all instances found and enumerate each. -
Pass criteria: The login endpoint is protected against CSRF via one or more of: a CSRF token validated server-side,
SameSite=Strictsession cookies, or an auth library that includes built-in CSRF protection (NextAuth, Clerk). The protection covers the POST that establishes the session. At least 1 implementation must be confirmed. -
Fail criteria: Custom login endpoint accepts POST requests with no CSRF token validation and uses cookies with
SameSite=Noneor unsetSameSite. No Origin/Referer validation present. -
Skip (N/A) when: Application uses only JSON API authentication with bearer tokens (no cookies) — CSRF requires cookie-based sessions. Signal: auth is entirely stateless JWT with no session cookies.
-
Cross-reference: The
session-tokens-securecheck verifies the cookie security flags that complement CSRF token validation. -
Detail on fail:
"Login endpoint at /api/auth/login accepts POST with session cookies but has no CSRF token, no Origin validation, and cookies use SameSite=None". -
Remediation: CSRF on a login endpoint allows an attacker to log victims into an attacker-controlled account (login CSRF), enabling account takeover indirectly. If using NextAuth, CSRF protection is already built in — verify you're using the standard signin flow:
// NextAuth handles CSRF automatically via csrfToken // Your custom login form should POST to /api/auth/callback/credentials // with the csrfToken from /api/auth/csrf // For custom endpoints, validate CSRF token: import { csrf } from '@edge-csrf/nextjs' const csrfProtect = csrf({ cookie: { secure: true } }) export async function POST(request: Request) { const csrfError = await csrfProtect(request) if (csrfError) return Response.json({ error: 'Invalid CSRF token' }, { status: 403 }) // ... login logic }Setting
SameSite=Laxon session cookies provides meaningful protection in modern browsers as a defense-in-depth measure.
External references
- cwe · CWE-352 — Cross-Site Request Forgery (CSRF)
- owasp:2021 · A01
- capec · CAPEC-62 — Cross-Site Request Forgery
- pci-dss:4.0 · Req-6.2.4
Taxons
History
- 2026-04-18·v1.0.0·Initial import from saas-authentication·automated