OAuthLib: Bearer token can be retrieved as long as client knows a valid client ID for device workflow
CVE-2026-49272 · GHSA-3jp2-3mrg-2vxc · published 27 Oct 2026
How serious is it
- Severity: high, CVSS score 8.5 out of 10.
- No exploit prediction (EPSS) score yet.
- Not on the CISA list of exploited vulnerabilities.
- No public exploit in Exploit-DB.
Is your app affected by CVE-2026-49272?
Paste this prompt into Claude Code, Cursor or any AI coding tool: it runs a free Shippable scan of your project and fixes what it finds. Built with Lovable, Bolt or v0? Scan your live app. Or upload your package file.
Who is affected
oauthlib(PyPI) >= 3.3.0, < 4.0.0
How to check
- Run
pip show oauthlibin your project to see the installed version, including copies pulled in by other packages. - Or paste your lockfile into the checker: it lists every package with a known vulnerability, this one included.
- Or run
npx shippable-dev scan localhost:3000in your project folder. It reads your lockfile and flags this vulnerability along with every other known one.
How to fix
Copies a prompt for Claude Code, Cursor or Codex: it checks your lockfiles for this and upgrades it.
- Upgrade
oauthlibto 4.0.0 or later, commit the lockfile and redeploy. - If a vulnerable version was live, check your logs and rotate the secrets that server could read.
The advisory
### 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](https://datatracker.ietf.org/doc/html/rfc8628#section-3.4) 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](https://github.com/oauthlib/oauthlib/blob/a015b446622f2b925517501fe484c10eff7a83c0/oauthlib/oauth2/rfc6749/grant_types/authorization_code.py#L446) and [here](https://github.com/oauthlib/oauthlib/blob/a015b446622f2b925517501fe484c10eff7a83c0/oauthlib/oauth2/rfc6749/grant_types/authorization_code.py#L483).
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": <ID of the public client you made>,
"grant_type": "urn:ietf:params:oauth:grant-type:device_code",
"device_code": <anything you want since it's not validated>
}
```
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.
Check your whole app
Dependencies are only half of it. Free and read-only: before you push, run npx shippable-dev scan localhost:3000 in your project folder, no account needed. For your live app, you prove it's yours with a one-line tag first.
References
- github.com/oauthlib/oauthlib/security/advisories/GHSA-3jp2-3mrg-2vxc
- github.com/oauthlib/oauthlib/releases/tag/v4.0.0
- github.com/advisories/GHSA-3jp2-3mrg-2vxc
- github.com/oauthlib/oauthlib
Merged from GitHub Advisory Database, OSV. Last updated 28 Oct 2026. All vulnerabilities · RSS · JSON