JWT로 세션을 관리하지 마십시오.

세상에는 JWT(JOSE/JWS/JWE)로 세션 관리를 해서는 안 된다는 기사가 2017년부터 산 정도 있는데 왠지 JWT에서 세션 관리를 하려고 하는 사람이 있다. 번역 기사이거나 암호의 설명이 너무 길거나 해서, JWT를 세션에 사용해 버리는 것 같은 사람의 마음에 찔리지 않았을까.

전제



JWT에서 세션 관리라고 하는 것은, 암호화한 토큰을 브라우저의 쿠키에 갖게 해, 서버측에서는 토큰을 복호화해 유저 판정 등의 세션 관리를 행하는 것이다. 서버측에서 [sessionId: userId]의 쌍을 관리할 필요가 없기 때문에 스테이트리스에 취급할 수 있어 스케일하기 쉽다는 장점이 있다.

문제



굉장히 편리한 그림이 있었으므로 우선 이것을 읽었으면 좋겠다. 세션 방식의 책정/설계를 하는 직위의 사람이라면 순조롭게 읽을 수 있다고 생각한다.



작은 3k. 오 rg 보다 인용 1

왼쪽에서 네 번째 Local Storage는 읽고 그대로 더 이상 보충하지도 않는다. 나머지는 다음 두 점으로 집계된다.

명시적으로 로그아웃하려면 서버 측 개인 키 변경이 필요합니다.



이 때문에 다음 두 가지를 강요당한다.
  • 누군가 한 사람이라도 로그아웃하고 싶을 때는 전원 로그아웃이 된다(비밀키를 갱신했을 경우)
  • 스푸핑 로그인이 발생하더라도 토큰 만료 시간이 올 때까지 세션을 비활성화 할 수 없습니다 (개인 키를 업데이트하지 않고 참을 경우)

  • 이것이 허락되는 것은 금전의 얽히지 않는 서비스인가, 유저에게 손해가 있어도 운영이 포인트를 나누면 끝나는(사죄석 대응)류의 서비스 등에 한정될 것이다. 하지만 보안은 단단히 문지른 적이 없다. 가상화폐거래사이트에서 후자를 선택하면 범인이 외부로 송금해 나가는 로그를 손가락을 물어보고 있을 수밖에 없다.

    기존 세션 관리는 더 낫습니다.



    전항의 불편함을 회피하기 위해서, 다음과 같은 회피책을 생각할지도 모른다.
  • 명시적으로 로그아웃한 사용자를 잘못된 토큰으로 관리
  • 사용자가 비밀번호를 변경하면 토큰도 다시 발행해야 합니다.

  • 결국 서버 측에서의 스테이트풀한 세션 관리이며, JWT의 장점인 스테이트리스를 버리고 있다. 신규로 구현하는 것보다, 종래의 시들어 있는 세션 관리 구현을 사용하는 편이 알기 쉽게 버그의 간과도 적을 것이다.

    인증



    세션 관리가 아니라 OAuth 인증 등에 사용하는 것은 문제 없다. 한번 인증하면 끝이므로 유효기한을 짧게 해 두면 된다. '혼자를 위해 전원 로그아웃' 같은 불편은 발생하지 않는다.

    소감



    일부 구현이 alg 헤더에 none(암호화 없음)을 허가했다든가, 어떤 암호화 방식에 어떤 약점이라든지, 화제가 분산되면 어디가 중요한지 알기 어려워진다. RFC를 읽을 수 있다고 하면 거부반응을 나타내는 사람도 있다. 제대로 간단하게 전하는 것은 어렵습니다.

    참고 URL



  • No Way, JOSE! Javascript Object Signing and Encryption is a Bad Standard That Everyone Should Avoid (PARAGON INITIATIVE, 2017-03-14)

  • JOSE (JavaScript 객체에 서명 및 암호화)는 절대로 피해야 할 나쁜 표준입니다. (POSTD, 위의 PARAGON 기사 번역, 2017-04-13)

  • 왜 리스크 평가 없이 JWT를 세션에 사용해 버리는 거야? (co3k.org, 2018-09-20)

  • JWT를 세션 관리로 전환하는 것은 그다지 좋은 아이디어가 아닙니다 (인증 만 있으면 좋다) (anatoo 블로그, 2018-10-03)



  • 원본 영어 버전은 @joepie91 씨 

    좋은 웹페이지 즐겨찾기