Skip to content
Usuario

CORS, CSRF y Cookies

Cuando el navegador autentica con cookies, CORS, CSRF y cookies forman una sola superficie de seguridad.

Reglas:

  • CORS_CREDENTIALS=true solo con allowlist exacta.
  • Nunca usar * con credenciales.
  • Reflejar solo origenes permitidos.
  • Enviar Vary: Origin cuando se refleja origen.
  • Permitir X-CSRF-Token en preflight.
  • OPTIONS no debe requerir auth, pero debe rechazar origen no permitido.
  • Authorization puede seguir permitido para compatibilidad legacy/no navegador, pero el navegador no debe depender de el.
CasoRequestEsperado
Origin permitidoOPTIONS /api/auth/login con Origin: https://app.<dominio>204, Access-Control-Allow-Origin exacto, credentials true.
Origin no permitidoOPTIONS /api/auth/login con Origin: https://evil.example403, sin credentials.
Sin OriginGET /api/auth/session sin OriginPasa a app, sin reflejar wildcard.
Header CSRFPreflight con Access-Control-Request-Headers: X-CSRF-TokenHeader permitido.
WildcardCualquier response autenticada por cookiesNo debe aparecer Access-Control-Allow-Origin: * con credentials.

Modelo implementado:

  • Signed double-submit.
  • Cookie CSRF no HttpOnly.
  • Header X-CSRF-Token.
  • Cookie y header deben coincidir.
  • Firma HMAC con CSRF_TOKEN_SECRET.
  • Binding preauth o session.
  • Origin/Referer como defensa adicional.
CasoEsperado
Sin header403 CSRF_FORBIDDEN, reason missing_header.
Header invalido403 con reason malformed, bad_signature, mismatch o equivalente.
Cookie ausente403 missing_cookie.
Cookie/header no coinciden403 mismatch.
Origin no permitido403 origin_not_allowed.
Token expirado403 expired.
Token validoRequest alcanza el controller o siguiente middleware.

Production-like:

AUTH_COOKIE_ACCESS_NAME=__Host-medsync_at
AUTH_COOKIE_REFRESH_NAME=__Host-medsync_rt
AUTH_CSRF_COOKIE_NAME=__Host-medsync_csrf
AUTH_COOKIE_SECURE=true
AUTH_COOKIE_SAMESITE=lax
AUTH_COOKIE_DOMAIN=
AUTH_COOKIE_PATH=/
AUTH_COOKIE_MAX_AGE_MODE=session

Validaciones:

  • __Host-medsync_at y __Host-medsync_rt: HttpOnly=true.
  • __Host-medsync_csrf: HttpOnly=false.
  • Todas: Secure=true, SameSite=Lax, Path=/.
  • Ninguna __Host- debe tener Domain.
  • Logout expira las tres cookies.

Solo para desarrollo:

AUTH_COOKIE_MODE=d2
BROWSER_AUTH_TRANSPORT=cookie
AUTH_COOKIE_ACCESS_NAME=medsync_at_dev
AUTH_COOKIE_REFRESH_NAME=medsync_rt_dev
AUTH_CSRF_COOKIE_NAME=medsync_csrf_dev
AUTH_COOKIE_SECURE=false
AUTH_COOKIE_SAMESITE=lax
AUTH_COOKIE_DOMAIN=
AUTH_COOKIE_PATH=/
AUTH_COOKIE_MAX_AGE_MODE=session
CSRF_ENABLED=true
CORS_CREDENTIALS=true

No uses esta configuracion para staging ni produccion.

SintomaCausa probableRevision
Login 403Falta CSRF o Origin no permitido./api/auth/csrf, header X-CSRF-Token, CSRF_ALLOWED_ORIGINS.
Browser no guarda cookiesSecure con HTTP local o SameSite/Domain incorrecto.DevTools cookies y flags.
Frontend recibe 401 tras login/api/auth/session no recibe access cookie.withCredentials, CORS credentials, cookie domain/path.
Preflight fallaHeader/metodo no permitido.CORS_ALLOWED_HEADERS, CORS_ALLOWED_METHODS.
Cookie no se limpia en logoutAtributos de clear no coinciden.Path/domain/samesite/secure iguales al set.