Refresh Token Rotation

Bty·2022년 1월 6일
post-thumbnail

보통은 유효 기간을 길게 설정하는 Refresh Token을
조금 더 안전하게 보관하고 사용할 수 있는 방법에 대해 살펴보다가,

Refresh Token Rotation에 대해 알게 되어
이에 대해 간단히 글을 작성해보고자 한다.


Refresh Token의 존재 이유

일반적으로 보안성을 높이기 위해 도입되었다는 견해가 있지만,
정확히 말하자면 사용자의 편의를 위해 도입되었다고 보는 게 맞다고 생각한다.

보안만을 고려하게 된다면 Access Token의 유효 기간을 짧게 설정하고
Refresh Token을 사용하지 않거나,
서버의 확장성 및 DB 요청 시간 등의 성능을 고려하지 않고
세션 기반 로그인 방식을 도입하겠지만

Access Token의 유효 기간을 짧게 설정하면
사용자가 로그인을 지속적으로 수행해주어야 한다는 점에서
사용자가 번거로움을 느낄 수 있다.

그러므로 Refresh Token의 도입이 보안 관점에서 도움이 된다는 것이
명백하게 틀린 말은 아니지만,
사용자의 편의를 위해 도입되었다고 보는 것이 맞다고 생각한다.

사용자에게 편리한 서비스를 제공하는 것은 매우 중요하다.
서비스에 대한 사용자의 지속적인 참여는 사용자가 다른 서비스로 전환하는 것을 어느 정도 막아줄 수 있고,
이는 기업의 수익에도 영향을 미칠 수 있다.
그 예시가 쇼핑 사이트라면, 체감이 될 것이다.

Refresh Token의 Security Issue

Refresh Token의 도입으로,
Access Token의 유효 기간을 짧게 설정할 수 있게 되었다.

Access Token의 짧은 유효 기간 덕에,
Access Token의 탈취되었을 때의 피해를 그나마 최소화 할 수 있게 되었다.

그렇다면 Refresh Token이 탈취되었을 경우를 살펴보자.

Refresh Token은 일반적으로 유효기간을 길게 설정한다.
Refresh Token의 유효기간도 짧게 설정한다면,
결국 사용자가 로그인을 자주 수행해주어야 하고,
Refresh Token을 도입했을 때의 이점이 사라지는 것이기 때문이다.

Token의 유효 기간을 길게 설정하는 것은 보안 관점에서 큰 위험이 존재한다.
일반적으로 stateless token은 유효 기간이 끝나기 전까지는
서버에서 직접 만료시킬 수 없기 때문에
토큰이 탈취되어도 서버에서 이를 감지할 방법이 없다.

해킹 위험으로부터 완전하게 보호해줄 수는 없지만,
Refresh Token의 탈취에 대한 위험을 어느 정도 완화시켜주는
Refresh Token Rotation에 대해 알아보자.

Refresh Token Rotation

큰 틀은 간단하다.
서버에 만료된 Access Token의 요청이 들어왔을 때,
새로운 Access Token을 발급해주면서 동시에
새로운 Refresh Token도 발급해주는 것이다.

아래의 flow는
PKCE(Authorization Code Flow with Proof Key for Code Exchange)
flow를 간단하게 나타낸 것인데,

PKCE에 대해서는 다음에 살펴보도록 하고 우선은
Refresh Token이 새로 발급되는 과정만 확인하자.

6번 과정에서 Access Token이 만료되고,
Client가 새로운 Access Token 발급을 요청하고,
새로운 Access TokenRefresh Token을 발급 받는 것이다.

단순히 Refresh Token도 새로 발급해주는 것 뿐인데,
어떻게 Refresh Token 탈취에 대한 위험을 완화시켜줄 수 있는지
조금 더 자세히 살펴보자.

Rotation의 원리

AT : Access Token, RT : Refresh Token을 의미한다.

앞서 언급 했듯이, Access Token이 만료 되면 Refresh Token을 이용해
새로운 Access Token을 발급받고, Refresh Token도 새롭게 발급 받는다.

단순히 Refresh Token도 새로 발급받는 것이
보안 측면에 큰 도움이 되지는 않을 것으로 보이지만,

Refresh Token Rotation의 도입으로
Refresh Token의 재사용을 감지하는 것이 가능해진다.

다음의 사례를 살펴보자.

해커가 사용자의 RT2를 탈취하였고,
사용자는 이에 대해 알지 못한 채 평소처럼 토큰을 새로 발급 받아
AT3RT3을 가지고 있는 상태이다.

이 상황에서 해커가 RT2를 통해 서버에 요청하게 된다면,
서버는 Refresh Token의 재사용을 감지하고,
Refresh Token을 만료시킬 수 있다.

반대의 경우도 마찬가지이다.

해커가 RT2를 탈취하고 이를 이용해 AT3, RT3을 발급받은 상황이다.
여기서 기존의 사용자가 만료된 RT2를 통해 서버에 요청할 경우,
마찬가지로 Refresh Token의 재사용을 감지하고
Refresh Token을 만료시킬 수 있다.

Auth0에서 게시한 Refresh Token Rotation 예시는 다음과 같다.

마찬가지로 악의적인 사용자가 Refresh Token을 탈취하고,
사용했을 때 만료된 Refresh Token의 재사용을 감지하고
이에 대한 접근을 거부하게 된다.

토큰의 재사용 시간 간격 설정

사용자가 만료된 Refresh Token을 재사용하는 경우도 있을 수 있다.

사용자가 새로운 Access Token을 발급받기 위해
만료된 Refresh Token으로 서버에 요청하고,

서버가 새로운 Access Token과 Refresh Token을 발급 후
이를 사용자에게 반환해주는 과정에서
네트워크 오류가 발생해 사용자가 Token을 발급받지 못하는 경우가 있다.

사용자는 다시 페이지 새로고침 등을 통해
다시 서버에 만료된 Refresh Token을 사용해 요청하면,
서버가 이를 악의적인 사용자가 만료된 Refresh Token을 사용했다고 판단하고
사용자를 로그인 페이지로 리다이렉트 시킬 수도 있다.

그렇기 때문에, 토큰의 재사용 허용 시간 간격을 어느 정도 짧게 설정하는 것도
나쁘지 않은 선택이다.

막을 수 없는 공격

Refresh Token Rotation의 도입으로,
Refresh Token이 탈취되고 사용되었을 경우의 피해를 최소화할 수 있게 되었다.

그렇다면 Access Token이 탈취된 경우라면 어떨까?
해커가 다음과 같이 탈취를 시도한다고 가정해보자.

해커가 XSS에 대한 취약점을 확인하고 Access Token을 탈취한 상황이다.
여기서 해커는 해당 서버가 Refresh Token Rotation이 적용되었다는 것을 알고
Refresh Token을 사용하지 않고, Access Token만 사용한다.

서버는 탈취된 Access Token를 사용한 요청이
악의적인 요청인지, 기존 사용자의 요청인지 구분할 수 없다.

보완 방법

서버는 앞서 언급한 사례와 같은 경우,
Access Token의 재사용을 감지할 수 없고 해당 Token을 만료시킬 수 없다.
Token의 유효 기간이 지나 자동적으로 만료가 되기 까지 기다리는 수 밖에 없다.

그렇기 때문에 우선 Token의 유효 기간을 항상 짧게 설정하는 것이 중요하고,
XSS 등에 대한 악의적인 공격에 대한 방어가 철저히 이루어져야 한다.

다른 방법으로는 BFF PatternReference Token을 사용하는 것이다.

결론

Refresh Token은 토큰 만료 및 Access Token 발급을 위해
서버에 저장되어야 하기 때문에
stateless 특성을 어느 정도 위배하게 된다.

하지만 해킹에 대한 공격을 100% 방어하면서, stateless 특성을 완벽하게 지키고,
높은 성능을 자랑하면서도 사용자의 편의를 완벽하게 보장하는 방법은 없다.

항상 보안과 기타 특성들에 대해 trade-off를 적절하게 고려하자.

Reference

profile
Better than yesterday

0개의 댓글