fix: CSRF protection is inert on all /api/* routes - #656
Conversation
The middleware matcher excluded /api, so applyCsrfProtection (imported and called in the middleware) never ran for any API route — CSRF was inert exactly where the mutating endpoints live. Include /api in the matcher and short-circuit API requests to CSRF-only, so the page-only logic (auth redirects, custom-domain rewrite, CSP nonce) still doesn't run on API calls. Fixes vishnukothakapu#646
|
@vedant7007 is attempting to deploy a commit to the vishnukothakapu's projects Team on Vercel. A member of the Team first needs to authorize it. |
📝 WalkthroughWalkthroughThe middleware now processes ChangesAPI CSRF Protection
Estimated code review effort: 3 (Moderate) | ~15 minutes Possibly related issues
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@middleware.ts`:
- Around line 14-16: Update the API branch in the middleware to match only the
exact `/api` path or paths beginning with `/api/`, rather than any pathname
starting with `/api`. Preserve the existing applyCsrfProtection flow for those
API paths and allow paths such as `/api-docs` and `/apiary` to continue through
the normal middleware handling.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
| if (pathname.startsWith("/api")) { | ||
| const csrfResponse = await applyCsrfProtection(req); | ||
| return csrfResponse ?? NextResponse.next(); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Restrict the API branch to an API path boundary.
Line 14 also matches non-API paths such as /api-docs and /apiary. Those requests skip page authentication redirects, custom-domain rewrites, and CSP handling. Match /api exactly or require the /api/ prefix.
Proposed fix
- if (pathname.startsWith("/api")) {
+ if (pathname === "/api" || pathname.startsWith("/api/")) {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (pathname.startsWith("/api")) { | |
| const csrfResponse = await applyCsrfProtection(req); | |
| return csrfResponse ?? NextResponse.next(); | |
| if (pathname === "/api" || pathname.startsWith("/api/")) { | |
| const csrfResponse = await applyCsrfProtection(req); | |
| return csrfResponse ?? NextResponse.next(); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@middleware.ts` around lines 14 - 16, Update the API branch in the middleware
to match only the exact `/api` path or paths beginning with `/api/`, rather than
any pathname starting with `/api`. Preserve the existing applyCsrfProtection
flow for those API paths and allow paths such as `/api-docs` and `/apiary` to
continue through the normal middleware handling.
Closes #646
Problem
applyCsrfProtectionis imported and invoked inmiddleware.ts, but the middlewareconfig.matcherexcludedapi("/((?!api|_next/...).*)"). So the middleware — and therefore the CSRF check — never ran for any/api/*route, leaving every mutating API endpoint unprotected.Fix
/apiin the matcher.applyCsrfProtection, so the page-navigation logic (auth redirects, custom-domain rewrite, CSP nonce) is not applied to API calls — preserving current behaviour for API routes apart from adding CSRF.The existing CSRF decision logic already scopes protection to POST/PUT/PATCH/DELETE and excludes safe paths (
/api/auth,/api/csrf,/api/contact-us,/api/links/click,/api/analytics/aggregate), so no legitimate request is affected.Testing
npx tsc --noEmitclean onmiddleware.ts.lib/csrf.test.ts,lib/middleware/csrf.test.ts) pass (8/8).Contributing as part of Elite Coders Summer of Code (ECSoC 2026).
Summary by CodeRabbit