Skip to main content Link Menu Expand (external link) Document Search Copy Copied

created at 2024-09-08

Authorization Code with PKCE(Proof Key for Code Exchange)

중간에 code 가로채고 먼저 accessToken 받아와서 해당 권한으로 리소스 서버에 접근하는 것을 막기 위한 프로토콜입니다. rfc 에 명시된 공격시나리오는 아래와 같아요.

PKCE

원리는 간단해요. 1번 과정에서 정상 앱은 secret_string(=code_verifier) 을 만들어서 hash(secret_string)(code_challenge) 를 만들고 이를 authorization server 로 보내면, 서버는 code_challenge 를 저장해놓고 code 를 앱으로 보내줍니다.

이 후, 정상 앱과 malicious 앱 둘 다 code 를 알게 되었습니다. 이제 legitimate 앱은 code 를 이용해서 access_token 을 받아오는데, 이 때 plain 한 code_verifier 를 함께 전달합니다. 또한 code_challenge 를 생성한 알고리즘(e.g. sha256)도 함께 전달하죠. malicious 앱은 전달할 code_verifier 를 모릅니다. 그래서 code 만을 보내죠. 하지만 authorization server 은 사전에 저장해둔 code 에 부여된 code challenge 가 있다는 것을 알고 있습니다. 그래서 아무런 code challenge 없이 code 만으로 access_token 을 받아오려는 시도를 거부합니다. 반면 legitimate 앱 은 code 와 code_verifier 를 함께 보냈죠? authorization server 는 code 에 부여된 code challenge 가 code_verifier 를 단방향 암호화한 값과 일치하는지 확인합니다. 일치하면 access_token 을 발급해줍니다.

이렇게 함으로써 authorization_code 가 하이재킹 되더라도 access_token 을 받아오는 것을 막을 수 있습니다 :) 이제 정상 앱이 accessToken 을 정상적으로 운용할 수 있게 되었습니다! 반면 웹 환경은 어떨까요?

뭐 웹 환경에서도 사용할 수 있습니다. 다만, 앱의 경우, iOS의 Keychain 및 Android의 Keystore 같은 안전한 저장소에 code_verifier 를 저장할 수 있지만, 웹은 저장할 공간이 마땅치 않습니다.

그래서 웹 환경에서는 클라이언트는 code_verifier 를 사용하지 않고, code 를 서버에 전달해 내부적으로 accessToken 받아서 처리하도록 합니다. 전통적이며 안전한 방법이죠.