Skip to content

[Security Critical] CSRF validation bypass allows unauthenticated state-changing requests via non-browser clients #7498

Description

@atul-upadhyay-7

Description

The CSRF validation in lib/security/csrf.ts explicitly bypasses all checks when neither Origin nor Referer headers are present:

// Allow server-to-server / tests
if (!origin && !referer) return null;

Any HTTP client that omits these headers (curl, Python requests, Postman, custom scripts) completely bypasses CSRF protection.

Affected Endpoints

All routes using validateCSRF():

  • POST /api/reviews — writes to MongoDB
  • POST /api/notify — writes notification preferences
  • POST /api/track-user — writes user tracking data
  • POST /api/student/resume/confirm — writes resume data

Proof of Concept

# Submit a spam review — no Origin/Referer header = CSRF bypass
curl -X POST https://commitpulse.vercel.app/api/reviews \
  -H 'Content-Type: application/json' \
  -d '{"name":"Attacker","handle":"evil","platform":"twitter","message":"spam"}'

The request succeeds because validateCSRF returns null (no error) when there is no Origin or Referer header.

Impact

  • Any programmatic client can write to MongoDB-backed endpoints without CSRF tokens
  • Combined with IP rotation (VPNs/proxies), an attacker can bypass rate limits and flood the database with spam/ malicious data
  • The /api/reviews endpoint is especially vulnerable — no GitHub ownership verification means anyone can submit fake testimonials

Recommended Fix

  1. For browser-facing endpoints, require either Origin or Referer header (reject requests missing both)
  2. OR implement proper CSRF token-based protection using signed cookies or double-submit patterns
  3. The current null return for missing headers was designed for server-to-server calls, but these endpoints are client-facing

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions