JWT가 탈취되면 어떻게 될까?

배준형·2022년 4월 5일
0
post-custom-banner

1. JWT의 동작 방식

토큰 인증 방식으로 로그인을 구현한 웹 서비스에서 유저가 성공적으로 로그인하게 되면 JSON 형태의 웹 토큰을 반환하게 되고, 해당 토큰에는 Header, Payload, Signature 등의 내용이 포함되어 있어 이를 통해 유저 인가(Authorization)가 가능하다.

이를 통해 유저가 서버의 자원(Resource)을 생성, 업데이트, 삭제 등의 요청(Request)할 때 JWT를 요청 Header에 담아 요청을 보내고, 서버에서는 유효한 토큰인지 확인한 후 응답(Response)하게 된다.


2. JWT를 이용한 토큰 인증 방식의 문제점

JWT를 사용한 인증 방식은 다음과 같은 이유로 장점이 많아 보인다.

  • 어떤 종류의 유저 정보든 JWT 형태로 저장할 수 있다.
  • JWT의 Signature를 통해 서버는 JWT를 신뢰할 수 있고, 데이터베이스를 추가로 검색할 필요가 줄어든다.
  • 중앙화된 데이터베이스의 세션을 조정할 필요가 없다.

그러나, 세션 인증 방식에서 세션은 서버 측에서 사용자 데이터에 대한 포인터(Pointer) 역할을 하지만 토큰 인증 방식에서 토큰은 사용자 데이터가 직접 포함되기 때문에 JWT가 탈취되어 유저의 데이터가 유출될 가능성은 언제나 존재하고, JWT를 매 요청 시마다 Header에 담아 보내는 것은 서버 측 세션 방식에 비해 상대적으로 비용(Cost)이 높다.


3. 만약 JWT가 도용(Stolen) 당한다면?

JWT 내부에는 사용자에 대한 데이터도 담겨있다. 따라서 JWT가 악의적인 사용자(Attacker)에 의해 탈취된다면 해당 토큰의 계정의 아이디, 비밀번호를 모두 도용한 것과 동일하게 계정을 사용할 수 있게 된다.

이후 악의적인 사용자가 탈취한 JWT를 사용해 서버에 JWT를 담은 요청을 보낸다면 JWT 자체에는 문제가 없으므로 서버에서는 이를 구분할 방법이 없다.

이를 해결하기 위해서 JWT의 만료(Expire) 시간을 설정하여 탈취된 JWT를 만료시간 전까지만 사용되도록 만들 수는 있다. JWT의 만료 시간을 짧게 설정하면 토큰 인증 방식에서의 위험을 최소화할 수 있지만, 통상적으로 한 번 JWT를 탈취할 수 있는 악의적인 사용자라면 여러 번 탈취할 수 있을 것이고, 여러 번 탈취할 수 있다면 JWT의 수명이 아무리 줄어든다고 하더라도 위험은 그대로 존재하게 된다.


4. 해결 방법

위와 같은 이유로 JWT는 HTML5의 Storage API(Local Storage, Session Storage)에 저장하기 보다는 서버측의 쿠키(Cookie)에 저장하는 것이 권장된다.

JWT를 Web Storage에 저장한다면 악의적인 사용자는 Script를 통해(XSS, Cross Site Scripting) 접근할 수 있다. 따라서 JWT를 httpOnly 쿠키에 저장하여 HTTP 요청 시에만 사용되도록 한다면 Web Storage보다 접근하기 어려워진다.


※ TensorFlow

Cookie 외에도 JWT가 탈취되었음을 감지하고, 이를 통해 JWT를 취소하거나 클라이언트, 서버 환경을 점검할 수 있도록 만들 수는 있다.

쉽지는 않지만 TensorFlow 와 같은 머신 러닝 파이프라인을 구축한다면 비정상적인 패턴을 감지하고 상황을 사전에 처리할 수는 있다.


5. 정리

기존 로그인 인증 방식에 대해 포스팅할 때 세션 인증 방식, 토큰 인증 방식의 차이 | JWT가 무엇인지 초점을 맞춰서 정리했었다. 이때 JWT가 탈취되면 이를 무효화할 수 있는 방법은 없다고 정리했지만 자세히 생각해 보니 탈취되면 어떤 일이 일어날지에 대해서는 고민해 보지 않았던 것 같다. 그래서 따로 정리해 보는 시간을 한 번 더 가졌다.

결국, JWT가 탈취되면 탈취한 JWT를 이용해 아이디, 비밀번호를 도용한 것과 마찬가지의 작업이 가능해지고, 이를 해결하기 위해 Web Storage에 저장하는 것이 아닌 httpOnly Cookie에 저장하는 것이 더 권장된다는 사실을 알게 됐다.

참고

https://blog.logrocket.com/jwt-authentication-best-practices/

https://jwt.io/introduction

profile
프론트엔드 개발자 배준형입니다.
post-custom-banner

0개의 댓글