Files
Kordant/tasks/security-fixes/05-fix-cors-origin-env-var-validation.md
2026-05-29 09:03:47 -04:00

2.4 KiB

05. Fix CORS origin trust from unvalidated APP_URL env var

meta: id: security-fixes-05 feature: security-fixes priority: P1 depends_on: [] tags: [implementation, tests-required, medium-severity]

objective:

  • Validate APP_URL before trusting it as a CORS origin to prevent arbitrary origin injection

deliverables:

  • APP_URL validation in CORS middleware at web/src/middleware.ts
  • Domain pattern validation for environment-sourced CORS origins
  • Unit tests for CORS origin validation

steps:

  1. Examine the CORS middleware at web/src/middleware.ts:22-30
  2. Create a validateCorsOrigin(origin: string): boolean function that:
    • Parses the origin URL and validates the hostname format
    • Rejects wildcard patterns (*), empty origins, and non-HTTP(S) schemes
    • Optionally checks against a known domain allowlist
  3. Add validation of process.env.APP_URL before adding it to allowedOrigins
  4. Add a fallback: if APP_URL is missing or invalid, log a warning and exclude it from allowed origins
  5. Consider adding a VALID_CORS_ORIGINS env var for explicit allowlist configuration

tests:

  • Unit: validateCorsOrigin accepts https://app.kordant.com (valid HTTPS origin)
  • Unit: validateCorsOrigin rejects * (wildcard)
  • Unit: validateCorsOrigin rejects evil.com (missing scheme)
  • Unit: validateCorsOrigin rejects empty string and whitespace
  • Unit: validateCorsOrigin rejects http://localhost:9999 if not in the allowlist (configurable)
  • Integration: CORS middleware does not add invalid APP_URL to allowed origins

acceptance_criteria:

  • APP_URL is validated before being added to CORS allowed origins
  • Invalid or missing APP_URL is excluded with a warning logged
  • Wildcard origins are rejected
  • Legitimate HTTPS origins are accepted
  • No regression in existing CORS behavior for localhost and configured domains

validation:

  • cd web && bun test — all tests pass
  • Set APP_URL=evil.com and verify it is not added to allowed origins
  • Set APP_URL=https://app.kordant.com and verify it is accepted

notes:

  • Finding p8-005: The current code trusts process.env.APP_URL without any validation
  • If APP_URL is set at deployment time (e.g., in a Docker env file), the risk is lower but still present if the deployment pipeline is compromised
  • Consider using a structured env var like CORS_ORIGINS=https://app.kordant.com,https://admin.kordant.com instead