CVE-2026-49272
OAuthLib: Bearer token can be retrieved as long as client knows a valid client ID for device workflow
OAuthLib is an implementation of the OAuth request-signing logic for Python 3.6+. From 3.3.0 until 4.0.1, OAuthLib's RFC 8628 device workflow does not require DeviceCodeGrant.validate_token_request to check that the device_code parameter is present and valid. A caller whose client request is accepted by the configured validator and who knows a valid client ID enabled for the device workflow can submit a missing or bogus device code to the token endpoint and obtain a bearer token without completing device authorization. This issue is fixed in version 4.0.1.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- Low
- User interaction
- None
What an attacker can affect
- Confidentiality
- Low
- Integrity
- High
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
8.5
OAuthLib: Bearer token can be retrieved as long as client knows a valid client ID for device workflow
OAuthLib is an implementation of the OAuth request-signing logic for Python 3.6+. From 3.3.0 until 4.0.1, OAuthLib's RFC 8628 device workflow does not require DeviceCodeGrant.validate_token_request to check that the device_code parameter is present and valid. A caller whose client request is accepted by the configured validator and who knows a valid client ID enabled for the device workflow can submit a missing or bogus device code to the token endpoint and obtain a bearer token without completing device authorization. This issue is fixed in version 4.0.1.
- Record
CVE-2026-49272- CVSS 3.1
- 8.5 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:H/A:N - Weakness
- CWE-287
- Updated
- 2026-11-05
EUVDEUVD-2026-117800
8.5
OAuthLib is an implementation of the OAuth request-signing logic for Python 3.6+. From 3.3.0 until 4.0.1, OAuthLib's RFC 8628 device workflow does not require DeviceCodeGrant.validate_token_request to check that the device_code parameter is present and valid. A caller whose client request is accepted by the configured validator and who knows a valid client ID enabled for the device workflow can submit a missing or bogus device code to the token endpoint and obtain a bearer token without completing device authorization. This issue is fixed in version 4.0.1.
- Record
EUVD-2026-117800- CVSS 3.1
- 8.5 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:H/A:N - Updated
- 2026-11-05
GitHub AdvisoriesGHSA-3jp2-3mrg-2vxc
8.5
OAuthLib: Bearer token can be retrieved as long as client knows a valid client ID for device workflow
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": <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.
- Record
GHSA-3jp2-3mrg-2vxc- CVSS 3.1
- 8.5 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:H/A:N - Weakness
- CWE-287
- Updated
- 2026-11-05
NVD
8.5
OAuthLib is an implementation of the OAuth request-signing logic for Python 3.6+. From 3.3.0 until 4.0.1, OAuthLib's RFC 8628 device workflow does not require DeviceCodeGrant.validate_token_request to check that the device_code parameter is present and valid. A caller whose client request is accepted by the configured validator and who knows a valid client ID enabled for the device workflow can submit a missing or bogus device code to the token endpoint and obtain a bearer token without completing device authorization. This issue is fixed in version 4.0.1.
- Record
CVE-2026-49272- CVSS 3.1
- 8.5 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:H/A:N - Weakness
- CWE-287
- Updated
- 2026-11-05
OSV
8.5
OAuthLib: Bearer token can be retrieved as long as client knows a valid client ID for device workflow
OAuthLib is an implementation of the OAuth request-signing logic for Python 3.6+. From 3.3.0 until 4.0.1, OAuthLib's RFC 8628 device workflow does not require DeviceCodeGrant.validate_token_request to check that the device_code parameter is present and valid. A caller whose client request is accepted by the configured validator and who knows a valid client ID enabled for the device workflow can submit a missing or bogus device code to the token endpoint and obtain a bearer token without completing device authorization. This issue is fixed in version 4.0.1.
- Record
CVE-2026-49272- CVSS 3.1
- 8.5 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:H/A:N - Weakness
- CWE-287
- Updated
- 2026-11-07
OSVDEBIAN-CVE-2026-49272
8.5
OAuthLib is an implementation of the OAuth request-signing logic for Python 3.6+. From 3.3.0 until 4.0.1, OAuthLib's RFC 8628 device workflow does not require DeviceCodeGrant.validate_token_request to check that the device_code parameter is present and valid. A caller whose client request is accepted by the configured validator and who knows a valid client ID enabled for the device workflow can submit a missing or bogus device code to the token endpoint and obtain a bearer token without completing device authorization. This issue is fixed in version 4.0.1.
- Record
DEBIAN-CVE-2026-49272- CVSS 3.1
- 8.5 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:H/A:N - Updated
- 2026-11-06
OSVGHSA-3jp2-3mrg-2vxc
8.5
OAuthLib: Bearer token can be retrieved as long as client knows a valid client ID for device workflow
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": <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.
- Record
GHSA-3jp2-3mrg-2vxc- CVSS 3.1
- 8.5 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:H/A:N - Weakness
- CWE-287
- Updated
- 2026-11-05
OSVUBUNTU-CVE-2026-49272
8.5
OAuthLib is an implementation of the OAuth request-signing logic for Python 3.6+. From 3.3.0 until 4.0.1, OAuthLib's RFC 8628 device workflow does not require DeviceCodeGrant.validate_token_request to check that the device_code parameter is present and valid. A caller whose client request is accepted by the configured validator and who knows a valid client ID enabled for the device workflow can submit a missing or bogus device code to the token endpoint and obtain a bearer token without completing device authorization. This issue is fixed in version 4.0.1.
- Record
UBUNTU-CVE-2026-49272- CVSS 3.1
- 8.5 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:H/A:N - Updated
- 2026-11-07
OSVROOT-APP-PYPI-CVE-2026-49272 No score
CVE-2026-49272 in oauthlib - Patched by Root
Root has patched CVE-2026-49272 in the oauthlib package for Root:PyPI. Multiple fixed versions available.
- Record
ROOT-APP-PYPI-CVE-2026-49272- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
oauthlibPyPI |
3.3.0 up to 4.0.1 | 4.0.1 |
python-oauthlibDebian:12 |
All versions, plus listed versions 3.2.2-13.2.2-23.2.2-33.2.2-43.3.1-13.3.1-2 |
None known |
python-oauthlibDebian:13 |
All versions, plus listed versions 3.2.2-33.2.2-43.3.1-13.3.1-2 |
None known |
python-oauthlibDebian:14 |
All versions, plus listed versions 3.2.2-33.2.2-43.3.1-13.3.1-2 |
None known |
oauthlibPyPI |
3.3.0 up to 4.0.1, plus listed versions 3.3.14.0.0 |
4.0.1 |
oauthlibRoot:PyPI |
before 3.3.1+aikido.1 | 3.3.1+aikido.13.3.1+aikido.2 |
python-oauthlibUbuntu:16.04:LTS |
All versions, plus listed versions 1.0.0-11.0.3-1 |
None known |
python-oauthlibUbuntu:18.04:LTS |
All versions, plus listed versions 2.0.1-12.0.4-12.0.6-1 |
None known |
python-oauthlibUbuntu:20.04:LTS |
All versions, plus listed versions 2.1.0-13.1.0-1ubuntu13.1.0-1ubuntu2 |
None known |
python-oauthlibUbuntu:22.04:LTS |
All versions, plus listed versions 3.1.0-23.1.1-13.2.0-13.2.0-1ubuntu0.1 |
None known |
python-oauthlibUbuntu:24.04:LTS |
All versions, plus listed versions 3.2.2-1 |
None known |
python-oauthlibUbuntu:26.10 |
All versions, plus listed versions 3.3.1-1build13.3.1-2 |
None known |
python-oauthlibUbuntu:26.04:LTS |
All versions, plus listed versions 3.2.2-33.3.1-13.3.1-1build1 |
None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected, aliases, references | OSV | |
| affected, aliases, references | OSV | |
| references | NVD, OSV | |
| aliases | EUVD | |
| references | CVE List | |
| affected, references | OSV | |
| affected, description, facts, products, references, severity | CVE List, GitHub Advisories | |
| first indexed | GitHub Advisories, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-49272 is a high vulnerability (CVSS 8.5) in Oauthlib, published October 27, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.33%, the 26th percentile. Fixed in oauthlib 4.0.1.
References
github.com/oauthlib/oauthlib/security/advisories/GHSA-3jp2-3mrg-2vxc
github.com/oauthlib/oauthlib/pull/954
github.com/oauthlib/oauthlib/commit/77a5f1c8ce00da2b0b8c5f6e9cc129920085f114
github.com/oauthlib/oauthlib/releases/tag/v4.0.1
github.com/advisories/GHSA-3jp2-3mrg-2vxc
github.com/CVEProject/cvelistV5/tree/main/cves/2026/49xxx/CVE-2026-49272.json