GitHub Advisoryadvisory · PyPI
GHSA-3jp2-3mrg-2vxc OAuthLib: Bearer token can be retrieved as long as client knows a valid client ID for device workflow
HIGH
Official page ↗
- Aliases
- CVE-2026-49272
- Ecosystem
- PyPI
- Packages
- oauthlib
- Severity
- High
- CVSS vector
- CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:H/A:N
- Weaknesses
- CWE-287
- Reviewed
- 2026-10-27
Affected packages
• PyPI oauthlib: >= 3.3.0, < 4.0.0 → fixed in 4.0.0
Description
Summary
A call to the token endpoint with a grant type of `"urn:ietf:params:oauth:grant-type:device_code"` and a bogus `device_code` 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 `device_code` as a required parameter.`DeviceCodeGrant.validate_token_request` does not perform any validation of `device_code`. `DeviceCodeGrant.validate_token_request` should be validating that `device_code` was passed in as a parameter and that it is valid, similar to how `AuthorizationCodeGrant.validate_token_request` does the checks here and here.
I would like to propose a new method be added to `RequestValidator` called `validate_device_code` that is similar to the `validate_code` method and is called inside of `DeviceCodeGrant.validate_token_request`.
PoC
Create an implementation of `RequestValidation.authenticate_client` that returns `True` if the client's `client_type` is `"public"`. You would find yourself in this scenario because there's another issue with `DeviceCodeGrant.validate_token_request` where it doesn't properly handle public clients (see https://github.com/oauthlib/oauthlib/issues/919).
Create a client that has a `client_type` of `"public"` and set it's `grant_type` to `"urn:ietf:params:oauth:grant-type:device_code"`.
With this implementation of `RequestValidation.authenticate_client` done, use that validator for your token endpoint. Call the token endpoint with a body of
```
{
"client_id": ,
"grant_type": "urn:ietf:params:oauth:grant-type:device_code",
"device_code":
}
```
You now have a bearer token for the client without a valid `device_code`.
Impact
Anyone using the RFC 8628 device workflow in oauthlib that doesn't realize the `device_code` parameter is not being validated.
Related
Alias · not in database (1)
Weakness · CWE (1)
- CWE-287 Improper Authentication weakness