You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Gateway는 HttpOnly auth_token cookie를 인증 수단으로 사용하지만 cookie-authenticated state mutation에 중앙 CSRF 방어가 없다. CORS와 SameSite 설정만으로는 CSRF 보안 경계를 대체할 수 없다. 특히 non-local cookie가 SameSite=None이므로 unsafe mutation은 별도 request token과 exact Origin 검증 없이 활성화할 수 없다.
목표
Cookie authentication을 실제로 수용하는 모든 unsafe mutation에 일관된 signed double-submit CSRF, exact Origin과 Fetch Metadata 검증을 적용하고 public/Bearer/API-secret surface와 명확히 분리한다.
확정 방식
GET /api/v1/auth/csrf가 짧은 TTL의 signed token을 응답 본문으로 반환하고 같은 값을 host-only HttpOnly CSRF cookie로 설정한다.
Client는 token을 메모리에만 보관하고 unsafe request의 X-CSRF-Token으로 보낸다. URL, localStorage/sessionStorage, log, trace와 audit에는 저장하지 않는다.
서버는 header-cookie constant-time equality와 HMAC 서명을 검증한다. 서명 입력은 version, expiry, random nonce, 현재 auth session fingerprint와 active organization scope를 포함하며 auth cookie 원문은 token에 포함하지 않는다.
로그인 전 signup/login은 별도 HttpOnly anonymous seed에 결박된 pre-auth token을 사용한다. 로그인 성공, organization 전환, logout과 만료 뒤에는 새 token을 발급받아야 한다.
같은 session·organization·TTL 안의 token 재사용은 병렬 요청을 위해 허용한다. 다른 session/organization, logout 이후 또는 expiry 뒤 replay는 거부한다.
Google OAuth navigation/callback은 custom header를 사용할 수 없으므로 기존 signed one-time OAuth state/session 검증을 login-CSRF 경계로 유지하고 일반 cookie mutation 예외로 명시한다.
적용 범위
Cookie를 수용하는 POST, PUT, PATCH, DELETE
Signup, password login과 logout의 session 변경 surface
authenticated internal Chatbot과 향후 Conversation Memory mutation
공통 Client API adapter의 token bootstrap, rotation 및 CSRF 실패 1회 refresh/retry
중앙 집행과 route inventory
Gateway의 중앙 middleware/policy가 method, route audience/auth scheme과 cookie 존재를 기준으로 unsafe 요청을 판정한다.
Cookie-authenticated mutation은 개별 controller가 검사를 빠뜨려도 중앙에서 fail-closed한다.
Public, Bearer-only, API-secret, webhook surface는 명시적인 route inventory와 정책 enum으로만 면제한다. Public route에 login cookie가 함께 전송되어도 authenticated surface로 승격하거나 불필요한 CSRF 권한을 부여하지 않는다.
Architecture test는 등록된 모든 unsafe route가 cookie/pre-auth/public/Bearer/API-secret 중 정확히 하나로 분류되는지 검사하고 미분류·중복 분류를 실패시킨다.
검증 계약
browser unsafe request는 configured CORS_ORIGINS의 exact Origin을 필수로 하며 missing, null, malformed와 unlisted 값을 거부한다.
Sec-Fetch-Site가 제공되면 same-origin 또는 exact-Origin과 정합한 same-site만 허용하고 cross-site를 거부한다.
CORS preflight 성공을 CSRF 성공으로 간주하지 않는다.
JSON mutation은 application/json만 허용한다. 승인된 multipart upload는 exact route inventory, CSRF header와 Origin 검증을 모두 요구하며 simple form 우회로 사용하지 못하게 한다.
검증은 request body parsing, DB mutation, queue publish, provider call과 Memory write 전에 수행한다.
실패는 동일한 sanitized 403 auth.csrf_validation_failed를 반환한다. Audit/metric에는 token·Origin 원문 없이 bounded reason enum만 기록한다.
제외/분리
Public webhook/run/chatbot은 cookie를 인증 주체로 사용하지 않는 별도 route다.
Public route에 login cookie가 함께 전송되어도 optional authentication으로 승격하지 않는다.
API secret/Bearer-only server-to-server route는 별도 replay/rate-limit 계약을 사용한다.
문제
Gateway는 HttpOnly
auth_tokencookie를 인증 수단으로 사용하지만 cookie-authenticated state mutation에 중앙 CSRF 방어가 없다. CORS와 SameSite 설정만으로는 CSRF 보안 경계를 대체할 수 없다. 특히 non-local cookie가SameSite=None이므로 unsafe mutation은 별도 request token과 exact Origin 검증 없이 활성화할 수 없다.목표
Cookie authentication을 실제로 수용하는 모든 unsafe mutation에 일관된 signed double-submit CSRF, exact Origin과 Fetch Metadata 검증을 적용하고 public/Bearer/API-secret surface와 명확히 분리한다.
확정 방식
GET /api/v1/auth/csrf가 짧은 TTL의 signed token을 응답 본문으로 반환하고 같은 값을 host-only HttpOnly CSRF cookie로 설정한다.X-CSRF-Token으로 보낸다. URL, localStorage/sessionStorage, log, trace와 audit에는 저장하지 않는다.적용 범위
POST,PUT,PATCH,DELETE중앙 집행과 route inventory
검증 계약
CORS_ORIGINS의 exactOrigin을 필수로 하며 missing,null, malformed와 unlisted 값을 거부한다.Sec-Fetch-Site가 제공되면same-origin또는 exact-Origin과 정합한same-site만 허용하고cross-site를 거부한다.application/json만 허용한다. 승인된 multipart upload는 exact route inventory, CSRF header와 Origin 검증을 모두 요구하며 simple form 우회로 사용하지 못하게 한다.403 auth.csrf_validation_failed를 반환한다. Audit/metric에는 token·Origin 원문 없이 bounded reason enum만 기록한다.제외/분리
TDD
완료 조건
403을 반환하고 외부 side effect와 민감 audit payload가 없다.관련·소비 이슈