fix(GRO-2586): enforce trusted-origins allowlist on Better Auth CORS responses #219
Reference in New Issue
Block a user
Delete Branch "feature/GRO-2586-cors-origin-reflection"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Fixes a HIGH-severity pre-existing CORS misconfiguration surfaced in GRO-2585.
Better Auth reflects the request
Originheader intoAccess-Control-Allow-Originunconditionally, bypassing thetrustedOriginsconfiguration. WithAccess-Control-Allow-Credentials: truealso set, any attacker-controlled page could XHR/api/auth/sign-in/socialand read the OIDC authorize URL + state from the response body — enabling phishing flows or CSRF login priming.Changes
src/lib/auth-cors.ts(new):enforceAuthCors(requestOrigin, trustedOrigins, res)— wraps a Better Auth response, strippingAccess-Control-Allow-Origin/Access-Control-Allow-Credentialsfor untrusted origins and enforcing the correct headers for trusted ones.src/index.ts: Auth handler now callsenforceAuthCors()before returning Better Auth's response, enforcing the allowlist regardless of Better Auth's internal CORS behaviour.src/__tests__/authCors.test.ts(new): 6 regression tests — trusted origin passes, attacker origin stripped,undefinedorigin stripped, non-CORS headers preserved, second trusted origin allowed, empty-string origin treated as untrusted.UAT_PLAYBOOK.md§4.1: Added TC-API-1.29/1.30/1.31 CORS test cases.Acceptance criteria met
https://evil.example.comto/api/auth/sign-in/socialreturns noAccess-Control-Allow-Originheader.https://uat.groombook.devreturnsAccess-Control-Allow-Origin: https://uat.groombook.dev+Access-Control-Allow-Credentials: true.authCors.test.tsall pass.Updated UAT_PLAYBOOK.md §4.1 — added TC-API-1.29, TC-API-1.30, TC-API-1.31 for CORS origin enforcement.
Related: GRO-2586 | GRO-2585