Validate CSRF Tokens on All State-Changing Requests
Share
State-changing API routes without CSRF validation allow cross-site request forgery. Validate tokens on POST/PUT/PATCH/DELETE with known exemptions. [CWE-352 · A01:2021]
Why This Matters
prevents cross-site request forgery on mutation endpoints
Validate CSRF Tokens on All State-Changing Requests
Impact: HIGH (prevents cross-site request forgery on mutation endpoints)
Cross-Site Request Forgery (CSRF) tricks authenticated users into making unintended state-changing requests. If a user is logged into your app and visits a malicious page, that page can submit forms or fire fetch requests to your API endpoints using the user's cookies. Without CSRF validation, every POST, PUT, PATCH, and DELETE endpoint is vulnerable.
CSRF protection should be applied as middleware in the compose chain, with explicit exemptions only for endpoints that handle their own authentication (webhooks, OAuth callbacks, cron jobs).
Incorrect (no CSRF validation on mutation endpoints):
// app/api/rules/route.ts// ❌ No CSRF check — a malicious page can create rules on behalf of logged-in usersexport async function POST(request: NextRequest) { const session = await getSession() if (!session) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) } const body = await request.json() const rule = await db.rules.create({ user_id: session.user.id, ...body, }) return NextResponse.json(rule, { status: 201 })}