맞왜틀

쿠키 기반 인증 vs JWT, 그리고 CSRF와 SameSite 이야기 본문

면접/질문

쿠키 기반 인증 vs JWT, 그리고 CSRF와 SameSite 이야기

deo2kim 2025. 10. 27. 20:31
반응형

쿠키 기반 인증 vs JWT, 그리고 CSRF까지 완벽 정리

요즘 프론트엔드 개발을 하다 보면, JWT 인증쿠키 기반 인증을 모두 접하게 됩니다. 처음에는 “JWT는 토큰이라서 안전하고, 세션은 옛날 방식 아닌가?” 하는 오해가 생기기 쉬운데요. 이번 글에서는 두 방식의 차이부터, 실제 서비스에서 고려해야 하는 보안 이슈(CSRF, HttpOnly, SameSite)까지 정리해보려 합니다.


1. 쿠키, 세션, JWT 기본 개념

1-1. 세션 기반 인증

서버가 로그인 요청을 받으면, 해당 유저 정보를 세션 저장소(메모리, Redis 등)에 저장하고 세션 ID를 브라우저 쿠키로 내려줍니다.

Set-Cookie: sessionId=abc123; HttpOnly; Secure;

이후 요청마다 브라우저는 자동으로 이 쿠키를 포함시켜 요청을 보냅니다.

Cookie: sessionId=abc123

서버는 이 세션 ID로 사용자 정보를 식별합니다. 즉, 세션 ID가 곧 “로그인 상태를 증명하는 신분증”입니다.

1-2. JWT 기반 인증

JWT(Json Web Token)는 서버가 서명한 accessToken 자체에 인증 정보를 담아두는 방식입니다. 서버에 세션 저장소가 없고, 토큰만으로 인증이 가능합니다.


{
  "header": { "alg": "HS256", "typ": "JWT" },
  "payload": { "userId": 123, "role": "admin" },
  "signature": "서명값"
}

서버는 서명을 검증해 유효한 토큰인지 확인하고, payload의 정보를 읽어 인증을 수행합니다.


2. 쿠키 방식과 JWT 방식의 차이

구분 세션 기반 인증 JWT 기반 인증
저장 위치 서버 (세션 스토리지) 클라이언트 (JWT 자체)
확장성 서버 부하 증가 서버 간 공유 불필요 → 확장성 높음
만료 처리 서버에서 세션 삭제 가능 토큰 만료(`exp`) 시점까지 유효
보안 위험 세션 ID 탈취 Access Token 탈취

3. 세션 ID나 JWT가 탈취되면 위험한 이유

세션 ID나 JWT 모두 “로그인 상태를 증명하는 신분증”이기 때문에, 이 값이 탈취되면 공격자는 해당 사용자의 계정으로 행동할 수 있습니다. 이를 세션 하이재킹(Session Hijacking)이라고 합니다.

대표적인 공격 경로

  • XSS: 악성 스크립트를 통해 document.cookie로 쿠키 탈취
  • HTTP 통신 도청: HTTPS가 아닌 평문 통신에서 쿠키 노출
  • 세션 고정 공격: 공격자가 미리 발급받은 세션 ID를 유도

방어 방법

Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Strict;
  • HttpOnly: JavaScript에서 쿠키 접근 차단 (XSS 방어)
  • Secure: HTTPS 통신에서만 전송
  • SameSite: 외부 도메인 요청 시 쿠키 전송 제한 (CSRF 방어)

4. CSRF(Cross-Site Request Forgery)란?

CSRF는 “다른 사이트에서 인증된 사용자의 세션을 악용해 요청을 보내는 공격”입니다.

예를 들어 사용자가 A사이트에 로그인된 상태에서, 공격자가 만든 B사이트에서 자동으로 A사이트로 POST 요청을 보내면, 브라우저는 A사이트 쿠키를 자동으로 전송합니다. 결과적으로 사용자가 의도하지 않은 요청이 수행될 수 있습니다.


이때 사용자는 로그인된 상태의 쿠키가 자동으로 전송되기 때문에, 서버는 정상적인 요청으로 오인합니다.

✅ 방어 방법

  • SameSite 쿠키 설정: 외부 사이트에서 쿠키가 전송되지 않게 함
  • CSRF 토큰: 서버가 발급한 토큰을 함께 검증

5. 쿠키 기반 JWT 인증은 안전한가?

요즘은 JWT를 로컬스토리지에 저장하지 않고 HttpOnly 쿠키에 저장하는 방식이 보안적으로 권장됩니다.

  • XSS 방어: HttpOnly 쿠키는 JS로 접근 불가
  • 자동 전송: fetch 시 쿠키 자동 포함 (credentials: 'include')
  • ⚠️ CSRF 주의: 쿠키는 자동 전송되므로 SameSite 설정이 중요

즉, Access Token을 HttpOnly 쿠키에 저장하고, SameSite=Lax 또는 Strict 설정을 사용하면 매우 안전한 구조입니다.


6. 리프레시 토큰은 항상 같이 보내면 안 되나?

리프레시 토큰은 새로운 Access Token을 발급받기 위한 “마스터 키”이기 때문에, 모든 요청에 함께 보내면 탈취 시 피해가 매우 큽니다.

보통 아래처럼 별도의 경로로만 전송되게 합니다.


Path=/auth/refresh;
HttpOnly;
SameSite=Strict;

즉, Access Token은 여러 요청에 사용되고, Refresh Token은 오직 /auth/refresh 요청에서만 사용되도록 설계하는 것이 베스트 프랙티스입니다.


7. 정리

  • 세션이든 JWT든, 탈취되면 위험하다.
  • HttpOnly, Secure, SameSite 설정으로 쿠키 보호가 필수.
  • CSRF는 브라우저의 자동 쿠키 전송을 악용한 공격.
  • Access Token은 짧게, Refresh Token은 안전하게 별도 경로로 관리.

결론: “JWT를 쿠키에 담는 방식은 보안적으로 좋은 선택이지만, CSRF와 토큰 주기 관리까지 신경써야 완전한 인증 시스템이 된다.”


📚 참고 키워드

  • Session Hijacking
  • CSRF vs XSS
  • HttpOnly / Secure / SameSite 쿠키 속성
  • JWT Refresh Token Rotation
반응형