Skip to content

[BUG] CSRF Validation Bypass via Referer Prefix Matching Flaw #3168

Description

@nyxsky404

Bug Description

The custom CSRF protection function validateCsrf in src/lib/csrf.ts attempts to validate the HTTP Referer header against a list of allowed origins. However, it uses a naive string matching implementation: referer.startsWith(a).

If an allowed origin a is https://devtrack.com, the check does not verify a domain boundary (like a trailing slash). An attacker can register a domain like https://devtrack.com.attacker.com and host a malicious CSRF payload targeting state-changing API routes. The victim's browser will send Referer: https://devtrack.com.attacker.com/exploit, which incorrectly evaluates to true under .startsWith(). The CSRF protection is silently bypassed.

Steps to Reproduce

  1. Serve a local instance or use the production API.
  2. Send a POST request to a state-changing API route protected by validateCsrf.
  3. Set the Referer header to https://devtrack.com.attacker.com.
  4. Observe that the CSRF validation successfully passes.

Affected Area

API Routes

Screenshots

No response

Browser & OS

No response

Environment

Both

Additional Context

Suggested Fix:

  1. Use the native URL constructor to parse the referer header: const refUrl = new URL(referer);.
  2. Validate exactly against the origin: if (allowed.includes(refUrl.origin)) return { valid: true };.
  3. Ensure trailing slashes are consistently handled before comparison.

Metadata

Metadata

Assignees

Labels

gssoc:assignedGSSoC: Issue assigned to a contributor

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions