#378

GitHub: an OAuth app can exchange a code issued to another app

Openjychpopened 1d ago

Problem

GitHub refuses to exchange an authorization code that does not belong to the app asking for it. Its documentation of the token request errors says: "If the verification code you pass is incorrect, expired, or doesn't match what you received in the first request for authorization you will receive this error", with bad_verification_code and "The code passed is incorrect or expired." (Troubleshooting OAuth app access token request errors). The code comes from step 1 of the web flow, which is made for one client_id (Authorizing OAuth apps).

The emulator stores the client_id with each code but does not compare it on POST /login/oauth/access_token. With oauth_apps configured, app B can exchange a code issued to app A with B's own valid credentials, and receives a token for A's user. A test that checks an app rejects codes meant for another app, or that one app's code cannot be replayed by another, cannot fail against the emulator today.

Proposal

  • With oauth_apps configured, POST /login/oauth/access_token returns bad_verification_code ("The code passed is incorrect or expired.") when the code was issued to another client_id, in the same JSON body and status as the emulator's other bad_verification_code responses. The refused exchange does not consume the code, so the app it was issued to can still exchange it.
  • What stays as it is: an app exchanging its own code, single use of codes, incorrect_client_credentials, and the permissive mode without oauth_apps, where no client is validated.

Implementation

A working version with tests is on a fork branch: https://github.com/Unchallenged-com/emulate/tree/github-oauth-code-client. Happy to open a pull request for it.

Activity

0

No activity yet.