oauth2-server icon indicating copy to clipboard operation
oauth2-server copied to clipboard

Race condition when issuing access token from authorization code

Open pokej6 opened this issue 1 year ago • 3 comments

Issue

The OAuth2 specification has the following:

If an authorization code is used more than once, the authorization server must deny the subsequent requests.

This repository addresses this by revoking the authorization code after it has been used to generate an access token. However the way that is being done allows multiple concurrent requests to result in generated access tokens before the authorization code is revoked.

See https://github.com/thephpleague/oauth2-server/blob/master/src/Grant/AuthCodeGrant.php

public function respondToAccessTokenRequest(
        ServerRequestInterface $request,
        ResponseTypeInterface $responseType,
        DateInterval $accessTokenTTL
    ) {
        // OAuth client lookup, authorization code validation/verification, scope finalization, code challenge verification
...
        // Issue and persist new access token
        $accessToken = $this->issueAccessToken($accessTokenTTL, $client, $authCodePayload->user_id, $scopes);
        $this->getEmitter()->emit(new RequestAccessTokenEvent(RequestEvent::ACCESS_TOKEN_ISSUED, $request, $accessToken));
        $responseType->setAccessToken($accessToken);

        // Issue and persist new refresh token if given
        $refreshToken = $this->issueRefreshToken($accessToken);
...
        // Revoke used auth code
        $this->authCodeRepository->revokeAuthCode($authCodePayload->auth_code_id);

        return $responseType;
    }

An easy way to reproduce this with live debugging is to set a breakpoint prior to the revocation of the authorization code. Then make 2 or more requests with the authorization code to get an access token. Once both hit your breakpoint, allow the requests to finish. You will have 2 access codes/refresh codes/etc.

Suggestions

There are a couple options I can think of to remediate this problem.

  1. Add column data to the authorization code table which identifies if a code has been used already.
  2. Revoke the code as soon as validation/verification is finished but before generating tokens.

pokej6 avatar Oct 11 '22 21:10 pokej6