Refresh Token Rotation

개발하는 구황작물·2024년 4월 6일
0
post-thumbnail

💡 들어가기 전
이 글은 JWT 토큰을 알고 있다는 전제 하에 작성되었습니다.

AccessToken만 사용시 발생하는 문제점

AccessToken은 유효기간이 짧다. 이로 인해 잦은 로그인을 요구하여 사용자에게 불편함을 안겨 줄 수 있다.

그렇다고 유효기간을 길게 잡으면 만약 해커한테 털려도 유효기간이 만료될 때까지 손가락만 빨고 있어야 한다.

JWT의 stateless 특성상 서버가 상태를 보관하지 않고, 한번 만든 토큰에 대해 제어권을 가지고 있지 않기 때문이다.

AccessToken + Refresh Token 매커니즘

그래서 Refresh Token이라는 것을 같이 사용한다.
Refresh Token은 AccessToken에 비해 긴 유효기간을 가진다.

아래는 AccessToken과 RefreshToken을 활용한 Access Token 만료시 Refresh Token을 통해 재발급 받는 과정이다.

  1. Client 가 서버로 로그인
  2. Server에서 AccessToken, RefreshToken 생성, 이때 RefreshToken은 DB에 저장
  3. Client에게 AccessToken, RefreshToken 전송
  4. 시간이 지나 AccessToken이 만료된 상태로 Client가 Server로 접근한다.
  5. AccessToken이 만료된 것을 확인한 서버는 Client가 같이 가져온 RefreshToken을 서버에 저장된 RefreshToken과 비교 후, AccessToken을 재발급해준다.

위의 방식으로 AccessToken의 유효기간을 짧게 가져도 RefreshToken을 통해 보안성을 높일 수 있다.

그러나 위의 방식에도 문제는 있다.

만약 RefreshToken이 털리면(!) 탈취된 RefreshToken으로 계속 AccessToken을 발급받을 수 있다는 문제점이 있다.

RTR (Refresh Token Rotation)

RTR(Refresh Token Rotation) 은 위의 문제를 어느정도 막아줄 수 있다.

아래는 RTR의 플로우이다.

  1. Client 가 서버로 로그인
  2. Server에서 AccessToken, RefreshToken 생성, 이때 RefreshToken은 DB에 저장
  3. Client에게 AccessToken, RefreshToken 전송
  4. 시간이 지나 AccessToken이 만료된 상태로 Client가 Server로 접근한다.
  5. AccessToken이 만료된 것을 확인한 서버는 Client의 RefreshToken을 DB의 RefreshToken과 비교 후, 새로운 AccessToken과 RefreshToken을 생성한다.
  6. 새로 생성된 AccessToken과 RefreshToken을 Client에게 전달한다.

간단히 말해서 RefreshToken을 AccessToken이 만료되어 서버에게 요청하는 경우마다 새로 갱신해주는 방식이다.

이러한 경우 아래와 같은 상황을 막아줄 수 있다.

RTR의 한계

그러나 만약 Hacker가 정상 Client 보다 먼저 접근해서 AccessToken과 RefreshToken을 갱신받는다면 어떻게 될까?

  1. Client 가 서버로 로그인
  2. Server에서 AccessToken, RefreshToken 생성, 이때 RefreshToken은 DB에 저장
  3. Client에게 AccessToken, RefreshToken 전송
  4. Hacker가 RefreshToken 탈취
  5. Hacker가 먼저 RefreshToken을 가지고 Server로 접근
  6. Server는 RefreshToken을 DB에 저장된 RefreshToken과 비교 후, AccessToken과 RefreshToken을 새로 생성한다.
  7. Server는 AccessToken과 RefreshToken을 Hacker에게 전달한다.
  8. AccessToken이 만료된 Client가 서버로 접근한다.
  9. Server는 RefreshToken의 재사용을 감지하여 RefreshToken을 모두 무효화 한 후, Client에게 AccessDenied 응답한다.
  10. Hacker가 다시 만료된 AccessToken을 가지고 접근한다.
  11. 모든 RefreshToken이 무효화되었으므로 서버는 AccessDenied를 응답한다.

Hacker의 접근을 막을 수 있었으나 한번은 Hacker의 접근을 허용하게 된다.

결국은 이러나저러나 RefreshToken이 탈취될 위험성이 존재한다.

+) HTTP stateless 방식에 어긋나기도 한다

결론

실버불렛은 없다
여러 방법들을 적절히 사용해서 보완하는 수 밖에 없다.

  1. xss, csrf 방어
  2. AccessToken 유효기간 짧게하기
  3. AccessToken에 중요한 정보 넣지 않기
  4. RefreshToken은 HttpOnly, Secure한 쿠키에 저장하기

등등을 활용하면 어느정도는 안전한 보안정책을 만들 수 있을 것이다

profile
어쩌다보니 개발하게 된 구황작물

0개의 댓글