GHSA-3jp2-3mrg-2vxc: High severity pip/oauthlib vulnerability
Summary A call to the token endpoint with a grant type of "urn:ietf:params:oauth:grant-type:devicecode" and a bogus devicecode is able to get a bearer token as long as they know a valid client ID enabled for the device workflow.
Details
Section 3.4 of the RFC 8628 spec says that the token endpoint should take in devicecode as a required parameter.DeviceCodeGrant.validatetokenrequest does not perform any validation of devicecode. DeviceCodeGrant.validatetokenrequest should be validating that devicecode was passed in as a parameter and that it is valid, similar to how AuthorizationCodeGrant.validatetokenrequest does the checks here and here.
I would like to propose a new method be added to RequestValidator called validatedevicecode that is similar to the validatecode method and is called inside of DeviceCodeGrant.validatetokenrequest.
PoC Create an implementation of RequestValidation.authenticateclient that returns True if the client's clienttype is "public". You would find yourself in this scenario because there's another issue with DeviceCodeGrant.validatetokenrequest where it doesn't properly handle public clients (see https://github.com/oauthlib/oauthlib/issues/919).
Create a client that has a clienttype of "public" and set it's granttype to "urn:ietf:params:oauth:grant-type:devicecode".
With this implementation of RequestValidation.authenticateclient done, use that validator for your token endpoint. Call the token endpoint with a body of { "clientid": <ID of the public client you made>, "granttype": "urn:ietf:params:oauth:grant-type:devicecode", "devicecode": <anything you want since it's not validated> }
You now have a bearer token for the client without a valid devicecode.
Impact Anyone using the RFC 8628 device workflow in oauthlib that doesn't realize the devicecode parameter is not being validated.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
pip/oauthlibto a version that resolves this vulnerability.Fixed in 4.0.0 - Compensating control
Update DeviceCodeGrant.validate_token_request to require the device_code parameter and validate that it is valid, using a RequestValidator.validate_device_code method similar to validate_code.
Event History
Frequently Asked Questions
Who is exposed to this issue?
Deployments using OAuthLib's device authorization grant workflow are exposed if an attacker can reach the token endpoint and knows a valid client ID that is enabled for that workflow.
What does an attacker need to exploit it?
The attacker needs a valid client ID enabled for the device workflow. They can submit a token request using the device-code grant type with a bogus device_code and obtain a bearer token.
Does exploitation require a legitimate device code or user interaction?
No. The issue occurs because the device_code is not validated; a bogus value can be used. The provided information does not indicate any user interaction requirement.
What should be checked to determine exposure?
Check whether your application uses OAuthLib for device authorization grants and whether its token endpoint accepts the urn:ietf:params:oauth:grant-type:device_code grant type for configured client IDs.