Spec Violations in GitHub OAuth Implementation and Security Considerations
3 min readApr 19, 2022
Based on information in the “Authorizing OAuth Apps” page on GitHub Docs. The Japanese version is here.
Spec Violations
- The
response_type
request parameter of authorization request is missing. The parameter is mandatory. See RFC 6749 (The OAuth 2.0 Authorization Framework) Section 4.1.1 (Authorization Request). - The default format of token response seems
application/x-www-form-urlencoded
. The format must always beapplication/json
. See RFC 6749 (The OAuth 2.0 Authorization Framework) Section 5.1 (Successful Response). - Values in the
scope
response parameter in token response are “comma-delimited”. The delimiter must be “space”. See RFC 6749 (The OAuth 2.0 Authorization Framework) Section 3.3 (Access Token Scope). - The format of the
Authorization
header for resource access isAuthorization: token OAUTH-TOKEN
although the token response says"token_type":"bearer"
. The format must beAuthorization: Bearer OAUTH-TOKEN
. See RFC 6750 (The OAuth 2.0 Authorization Framework: Bearer Token Usage) Section 2.1 (Authorization Request Header Field). - The default format of device authorization response seems
application/x-www-form-urlencoded
. The format must always beapplication/json
. See RFC 8628 (OAuth 2.0 Device Authorization Grant) Section 3.2 (Device Authorization Response). - The default format of token response in the device flow seems
application/x-www-form-urlencoded
. The format must always beapplication/json
. See RFC 8628 (OAuth 2.0 Device Authorization Grant) Section 3.5 (Device Access Token Response). The section states “If the user has approved the grant, the token endpoint responds with a success response defined in Section 5.1 of [RFC6749];” - Values in the
scope
response parameter in token response in the device flow are “comma-delimited”. The delimiter must be “space”. RFC 8628 requires that token endpoint implementations conform to RFC 6749.
GitHub-Specific Extensions
- The
login
parameter of authorization request. Instead of introducing the GitHub-specific parameter, it is better to utilize thelogin_hint
parameter which is defined in OpenID Connect Core 1.0 Section 3.1.2.1 (Authentication Request). - The
allow_signup
parameter of authorization request. Instead of introducing the GitHub-specific parameter, it is better to utilizeprompt=create
which is defined in Initiating User Registration via OpenID Connect. - The token endpoint changes its response format according to the
Accept
header in the token request. No. The response format must always beapplication/json
. - The device authorization endpoint changes its response format according to the
Accept
header in the device authorization request. No. The response format must always beapplication/json
. - The following error codes that the token endpoint may return in the device flow are GitHub-specific. They are not defined in the standard specifications;
incorrect_client_credentials
,incorrect_device_code
,device_flow_disabled
Security Considerations
- Should support RFC 7636 (Proof Key for Code Exchange by OAuth Public Clients). To be concrete, the authorization endpoint should support the
code_challenge
andcode_challenge_method
request parameters and the token endpoint should support thecode_verifier
request parameter. The specification prevents attackers from exchanging a stolen authorization code with an access token at the token endpoint. Read “Proof Key for Code Exchange (RFC 7636)” for details about the specification. - Should support RFC 8705 (OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens) Section 3 (Mutual-TLS Client Certificate-Bound Access Tokens). If GitHub had supported the “certificate binding” specification, the impact of the security incident (“Security alert: Attack campaign involving stolen OAuth user tokens issued to two third-party integrators”) could have been drastically mitigated. The specification prevents attackers from using a stolen access token for resource access unless they have succeeded in stoling the client certificate of the victim client application, too. Read “Financial-grade API, explained by an implementer” for explanation about certificate binding.
- Should support securer client authentication methods at the token endpoint and the device authorization endpoint. In the traditional client authentication methods explained in the Section 2.3 (Client Authentication) of RFC 6749, the client secret is sent over the network. It should be avoided. As a matter of fact, the Financial-grade API specification prohibits the traditional client authentication methods. Read “OAuth 2.0 Client Authentication” for details about securer client authentication methods.
- Many other security enhancement specifications have been developed since RFC 6749 was published in October, 2012, which is about 10 years ago! For example, JAR (RFC 9101 The OAuth 2.0 Authorization Framework: JWT-Secured Authorization Request (JAR)), JARM (Financial-grade API: JWT Secured Authorization Response Mode for OAuth 2.0 (JARM)) and PAR (RFC 9216 OAuth 2.0 Pushed Authorization Requests). Should consult experts in Working Groups of OpenID Foundation.