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
- For browser-facing endpoints, require either
Origin or Referer header (reject requests missing both)
- OR implement proper CSRF token-based protection using signed cookies or double-submit patterns
- The current
null return for missing headers was designed for server-to-server calls, but these endpoints are client-facing
Description
The CSRF validation in
lib/security/csrf.tsexplicitly bypasses all checks when neitherOriginnorRefererheaders are present: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 MongoDBPOST /api/notify— writes notification preferencesPOST /api/track-user— writes user tracking dataPOST /api/student/resume/confirm— writes resume dataProof of Concept
The request succeeds because
validateCSRFreturnsnull(no error) when there is no Origin or Referer header.Impact
/api/reviewsendpoint is especially vulnerable — no GitHub ownership verification means anyone can submit fake testimonialsRecommended Fix
OriginorRefererheader (reject requests missing both)nullreturn for missing headers was designed for server-to-server calls, but these endpoints are client-facing