가희의자기개발블로그

[번역]JWT를 세션 메커니즘에 이용하지 말자 Part 1 -(1) 본문

웹 프로그래밍

[번역]JWT를 세션 메커니즘에 이용하지 말자 Part 1 -(1)

가희gahui 2021. 8. 9. 22:42
반응형

얼마전, 인턴을 했던 회사의 사수분과 이야기 하던중, Session과 JWT를 혼용해서 쓰는것에 대해 대화를 나눴다. 두개를 혼용해서 쓰면 안된다는 것을 알고는 있었지만, 왜 그러면 안되는지에 대해서 명확히 알고 있지 않아서 검색을 해보던 중, 좋은 글이 있어서 번역에 도전해봤다. 같은 글을 번역한 블로그글도 있었지만, 왜인지 중간에 끊겨있어서 정리할겸 포스팅을 결심했다. 


최근, 유저 세션을 관리하기 위해 JWT를 이용하라는 글이 많습니다. 정말 추천하지 않는 방법이고 제가 왜 그렇게 생각하는지 설명하겠습니다. 본격적으로, 글을 시작하기 앞서 먼저 몇가지 키워드를 정의하겠습니다.  

 

  • Stateless JWT: 세션 데이터를 포함하는 JWT토큰입니다. 토큰에 직접 인코딩 합니다. 
  • Stateful JWT: 세션의 참조값이나 ID를 포함하는 JWT토큰으로 세션 데이터는 서버사이드에 저장됩니다. 
  • 세션 토큰/쿠키: 주로 웹프레임워크에서 사용해 왔던 표준 세션 ID 입니다. 세션 데이터는 서버사이드에 저장됩니다.

이글은 JWT를 사용하지 말자고 주장하는 글이 아니라 세션 메커니즘으로서 JWT를 이용하는 것이 적합하지 않으며, 그렇게 사용하는 것은 위험하다는 글입니다. JWT를 사용하는데 적합한 유즈케이스들에 대해서는 이글의 마지막에 간단하게 설명하도록 하겠습니다.

 

 


보통 JWT와 쿠키를 비교하는 사람들이 있습니다. JWT와 쿠키는 비교대상이 아닙니다. 쿠키의 경우 저장 메커니즘이고 JWT는 암호화한 인증 토큰입니다. 

이는 같이 쓰일 수 있기 때문에, 서로 반대되는 개념이 아닙니다. 정확한 비교는 "세션 vs JWT" 그리고 "쿠키 vs 로컬 저장소"입니다. 

 


JWT의 이점에 대한 주장


일반적으로 사람들이 JWT를 사용하라는 이유로는 다음과 같습니다. 

 

  • 확장성이 편리하다.
  •  사용하기에 쉽다.
  •  유연성의 향상
  •  안정성의 향상
  •  expire 기능이 제공된다.
  •  쿠키 동의 여부를 물어볼 필요가 없다.
  •  CSRF 공격 방어
  •  모바일 환경에서 더 효과적이다. 
  •  쿠키를 차단한 사용자들에 관계없이 사용할 수 있다. 

이 포스트에서 각각의 주장이 틀렸다는 것을 다루겠습니다. 

 

확장성이 편리하다.

확장하기 쉽다는 이 주장은 stateless JWT 토큰을 사용할 경우에만 옳은 주장입니다. 그러나 실제로는 보통 이런 종류의 확장성을 필요로 하지 않는다는 것입니다. 확장하기위한 더 쉬운 방법이 많이 있으며,  Reddit 사이트와 같은 크기로 운영하지 않는 한 , 대부분 'Stateless 세션'이 필요하지 않습니다. stateful session을 확장하는것에 대한 예시로는 다음이 있습니다. 

 

  1. 서버에서 여러 백엔드 프로세스를 실행하면 세션 저장소에 대한 Redis 데몬을 서버에서 사용하면 된다. 
  2. 여러대의 서버에서 실행하는 경우:  세션 저장소를 위한 Redis 전용 서버를 분리하면 된다.  
  3. 여러 서버에서 실행한 후 여러 클러스터에서의 경우: Sticky Session을 이용하면 된다.

 

이는 실제 운영중인 서비스에서 아주 잘 지원되고 있는 방식입니다. 일반적으로 두번째 단계를 넘어가는 경우가 없다는 것을 고려하면, 확장하기 쉬우니 JWT를 써야 한다는 말은 김칫국부터 마시는 거랑 같다고 볼 수 있다. 아마도, 그 다음 단계를 넘어 확장해야하는 상황이 올지 모르니 그것을 미리 대비해야한다고 생각할 수도 있습니다. 그러나 세션메커니즘을 바꾸는 일은 모든 사용자들을 한번에 로그아웃 시키기만 하면 되기 때문에 매우 간단한 일입니다. 내가 겪을지 안겪을지 모르는 단점을 고려하면서 미리 JWT를 사용한다는 것은 그렇게 까지 의미있는 일이 아닙니다. 

 

사용하기에 쉽다.

JWT를 사용할 경우, 클라이언트와 서버 사이드 양쪽에서 세션 관리를 직접 수행해야합니다. 반면에 표준 세션 쿠키는 서버에서만 세션을 관리해도 잘 사용할 수 있습니다. JWT를 사용하기에 더 쉽다고 할 수 없습니다.

 

유연성 향상

사실 아직까지 JWT가 더 유연성이 높다는 것을 설명한 사람을 본적 없습니다. 이미 대부분의 주요한 세션 구현 방식들은 세션에 대해서 임의의 데이터를 추가로 저장할 수 있으며 이는 JWT의 작동 방식과 다르지 않습니다. 

 

안정성의 향상

많은 사람들이 JWT 토큰이 암호화를 사용하기 때문에 "더 안전하다"고 생각합니다. 보안적으로 signed 된 쿠키가 signed되지 않은 쿠키보다 더 안전하지만, 이것은 JWT만의 고유한 것이 아니며, 훌륭한 세션 구현도 보안적으로 signed된 쿠키를 사용합니다.

"암호화를 사용한다"는 것 또한 마법처럼 뭔가 더 안전한 것을 만드는 것이 아닙니다.  그것은 특정한 목적을 위해, 그리고 그 특정한 목적을 위한 효과적인 해결책이 되어야 합니다. 잘못 사용된 암호는, 오히려 더 안전하지 못하게 만들 수 있습니다.

JWT 가 '더 안전하다는' 주장에 대한 또 다른 설명은 'JWT가 쿠키로 전달되지 않는다'는 것입니다. 이건 전혀 말이 되지 않습니다. 쿠키는 HTTP 헤더일 뿐이고 쿠키를 사용하는 것이 안전하지 않은게 아닙니다. 오히려, 쿠키는 특히 해커가 심은 클라이언트 쪽 코드로부터 잘 보호될 수 있습니다. 

만약 누군가가 여러분들의 세션 쿠키를 가로채는 것이 걱정된다면, 당신은 그 대안으로 암호화 보안 프로토콜인 TLS를 사용할 수 있습니다. - 만약 여러분들이 JWT가 포함된 TLS를 사용하지 않는다면 어떤 종류의 세션 구현도 가로챌 수 있을 것입니다.

 

expire 기능이 제공된다.

이는 유용한 특징이 아닙니다. Expire Date 기능은 서버측에서도 충분히 구현 될 수 있습니다.  사실, 서버 사이드에서 만료 기능을 구현한다면, 더 이상 필요하지 않은 세션 데이터를 정리할 수 있습니다. 반면에, 토큰의 기간 만료 메커니즘을 위해 stateful JWT 토큰을 사용한다면 할 수 없는 일입니다. 그렇기 때문에 서버 사이드에서 만료기능을 구현하는게 더 선호되는 방식입니다.  

 

쿠키 동의 여부를 물어볼 필요가 없다.

완전히 틀린 말입니다. 어디에도 "쿠키 법"이라는 건 없습니다. 쿠키에 관련된 여러 법은 지속적인 식별을 위한것이지, 서비스 기능을 구현하는데 필수적이지 않습니다. 우리가 생각하는 모든 세션 메커니즘은 이에 적용됩니다. 

 

정리해 보자면, 

  • 유저의 로그인 상태를 유지시키는 것과 같이 어떤 기능적 목적을 위해서 세션이나 토큰을 사용한다면, 어떻게 세션을 저장할 것인지에대한 유저의 동의를 물을 필요가 없습니다.
  •  만약 분석이나 통계, 추적과 같은 다른 목적을 위해 세션이나 토큰을 사용해야한다면, 어떻게 세션을 저장할 것인지에대한 유저의 동의를 물을 필요가 있습니다.  

CSRF 공격 방어

전혀 그렇지 않습니다. JWT를 저장하는데에는 두가지 방법이 있습니다. 

 

  • 쿠키에 저장하는 방식 
    이 방식은 여전히 CSRF 공격에 취약합니다.
  •  다른 곳, ex 로컬 저장소 
    이 방식은 더이상 CSRF 공격으로부터 취약하지 않지만, 여러분들의 앱이나 사이트에 이를 동작시킬 JS 코드가 필요합니다. 하지만 이는 완전히 다른, 그리고 잠재적으로 좋지 않은 취약점을 만들어 냅니다. 여기에 대한 자세한 설명은 아래에서 다루도록 하겠습니다.

CSRF 공격을 완화 하기 위한 유일한 방법은 CSRF 토큰을 사용하는 것입니다. 이는 세션 메커니즘과 전혀 관계없는것입니다. 

 

모바일 환경에서 더 효과적이다.

사용 중인 모든 모바일 브라우저는 쿠키와 세션을 지원합니다. 모든 주요 프레임워크와 모든 HTTP 라이브러리도 마찬가지입니다. 이것은 전혀 문제가 되지 않습니다.

 

쿠키를 차단한 사용자에게도 동작한다.

유저는 쿠키를 차단하는게 아니라, 모든 종류의 저장/수집을 차단하는것입니다. 여기에는 JWT의 사용 여부에 관계없이 세션을 지속할 수 있는 기타 저장소나 로컬 스토리지에 저장하는 것을 포함합니다. JWT를 사용하는것과는 완전히 별개의 문제입니다. 그렇기 때문에, 유저의 쿠키 차단을 이유로 쿠키를 사용하지 않고 인증을 구현한다는 것은 의미 없는 일입니다. 

모든 쿠키를 차단하는 유저들은 대개 이것이 인증기능을 차단한다고 알고있기 때문에, 이에 대해 관심 있는 사이트에 한해 쿠키 차단을 해제합니다. 이건, 개발자가 상관해야하는 일이 아닙니다. 오히려, 더 나은 방법은, 사용자에게 왜 쿠키를 작동시켜야하는지 설명하는 것입니다.

반응형
Comments