Every CVE Search/ Get API key

CVE-2026-118669

OAuthLib: Token grants can use attacker-supplied client_id for authorization after authenticating a different client

8.4 HighFix available

OAuthLib is an implementation of the OAuth request-signing logic for Python 3.6+. Prior to 4.0.0, the client_credentials and Resource Owner Password Credentials token grant handlers can authenticate request.client as one confidential client while retaining an attacker-supplied request.client_id for validate_grant_type and validate_scopes. A lower-privilege authenticated client can therefore cause grant and scope authorization to use another client's identity when an application validator relies on the documented client_id argument, potentially issuing tokens with unauthorized grants or scopes. Validators that authorize exclusively from request.client may not be affected. This issue is fixed in version 4.0.0.

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
None
Integrity
High
Availability
None

Exploit likelihood

0.31%Unchanged since Oct 29, 2026
90%50%10%1%

What each source reports

CVE List Score used 8.4

OAuthLib: Token grants can use attacker-supplied client_id for authorization after authenticating a different client

OAuthLib is an implementation of the OAuth request-signing logic for Python 3.6+. Prior to 4.0.0, the client_credentials and Resource Owner Password Credentials token grant handlers can authenticate request.client as one confidential client while retaining an attacker-supplied request.client_id for validate_grant_type and validate_scopes. A lower-privilege authenticated client can therefore cause grant and scope authorization to use another client's identity when an application validator relies on the documented client_id argument, potentially issuing tokens with unauthorized grants or scopes. Validators that authorize exclusively from request.client may not be affected. This issue is fixed in version 4.0.0.

Record
CVE-2026-118669
CVSS 4.0
8.4 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:H/SI:H/SA:N
Weakness
CWE-863
Updated
2026-11-03
EUVDEUVD-2026-112488 8.4

OAuthLib is an implementation of the OAuth request-signing logic for Python 3.6+. Prior to 4.0.0, the client_credentials and Resource Owner Password Credentials token grant handlers can authenticate request.client as one confidential client while retaining an attacker-supplied request.client_id for validate_grant_type and validate_scopes. A lower-privilege authenticated client can therefore cause grant and scope authorization to use another client's identity when an application validator relies on the documented client_id argument, potentially issuing tokens with unauthorized grants or scopes. Validators that authorize exclusively from request.client may not be affected. This issue is fixed in version 4.0.0.

Record
EUVD-2026-112488
CVSS 4.0
8.4 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:H/SI:H/SA:N
Updated
2026-11-03
GitHub AdvisoriesGHSA-7984-qgvg-3j9c 8.4

OAuthLib: Token grants can use attacker-supplied client_id for authorization after authenticating a different client

Summary

OAuthlib's token grant handlers can authenticate one client while authorizing the grant type and requested scopes using a different, attacker-supplied client_id from the request body.

In affected token grant flows, authenticate_client(request) sets request.client to the authenticated client object, but OAuthlib does not require request.client_id to match request.client.client_id. If the request body already contains client_id=..., OAuthlib keeps that value and passes it to validate_grant_type() and validate_scopes().

As a result, an authenticated low-privilege confidential client can authenticate as itself, submit another client's client_id in the token request body, and cause grant and scope validation to run under that other client identity.

Affected Surface

The affected public surface is the OAuth2 token endpoint handling for:

  • client_credentials
  • password / Resource Owner Password Credentials

The issue is relevant to OAuthlib provider deployments where:

  • the attacker has credentials for one valid lower-privilege confidential client;
  • another client has broader grants or scopes;
  • the application validator uses the client_id argument passed by OAuthlib in validate_grant_type() or validate_scopes(), as the RequestValidator API is designed to support.

Deployments whose validators ignore the client_id argument and authorize only from request.client may not be affected.

Details

Request parses query and body parameters into request attributes, including client_id:

The RequestValidator.authenticate_client() contract requires the integrator to authenticate the client and set request.client:

For the client_credentials grant, OAuthlib authenticates the client, verifies that request.client has a client_id, then performs grant and scope validation before normalizing request.client_id from request.client.client_id:

The problematic order is:

if not self.request_validator.authenticate_client(request):
    ...
elif not hasattr(request.client, 'client_id'):
    ...

self.validate_grant_type(request)

request.client_id = request.client_id or request.client.client_id
self.validate_scopes(request)

Because OAuthlib only fills request.client_id when it is missing, an attacker-supplied body value such as client_id=high survives even when request.client.client_id == "low".

The shared grant helper then authorizes using request.client_id, while passing the authenticated client object separately:

The same identity split exists in the Resource Owner Password Credentials flow. After client authentication and user validation, OAuthlib validates the grant and scopes before replacing a missing request.client_id from request.client.client_id:

This creates an…

Record
GHSA-7984-qgvg-3j9c
CVSS 4.0
8.4 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:H/SI:H/SA:N
Weakness
CWE-863
Updated
2026-11-02
NVD 8.4

OAuthLib is an implementation of the OAuth request-signing logic for Python 3.6+. Prior to 4.0.0, the client_credentials and Resource Owner Password Credentials token grant handlers can authenticate request.client as one confidential client while retaining an attacker-supplied request.client_id for validate_grant_type and validate_scopes. A lower-privilege authenticated client can therefore cause grant and scope authorization to use another client's identity when an application validator relies on the documented client_id argument, potentially issuing tokens with unauthorized grants or scopes. Validators that authorize exclusively from request.client may not be affected. This issue is fixed in version 4.0.0.

Record
CVE-2026-118669
CVSS 4.0
8.4 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:H/SI:H/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Weakness
CWE-863
Updated
2026-11-03
OSV 8.4

OAuthLib: Token grants can use attacker-supplied client_id for authorization after authenticating a different client

OAuthLib is an implementation of the OAuth request-signing logic for Python 3.6+. Prior to 4.0.0, the client_credentials and Resource Owner Password Credentials token grant handlers can authenticate request.client as one confidential client while retaining an attacker-supplied request.client_id for validate_grant_type and validate_scopes. A lower-privilege authenticated client can therefore cause grant and scope authorization to use another client's identity when an application validator relies on the documented client_id argument, potentially issuing tokens with unauthorized grants or scopes. Validators that authorize exclusively from request.client may not be affected. This issue is fixed in version 4.0.0.

Record
CVE-2026-118669
CVSS 4.0
8.4 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:H/SI:H/SA:N
Weakness
CWE-863
Updated
2026-11-07
OSVDEBIAN-CVE-2026-118669 8.4

OAuthLib is an implementation of the OAuth request-signing logic for Python 3.6+. Prior to 4.0.0, the client_credentials and Resource Owner Password Credentials token grant handlers can authenticate request.client as one confidential client while retaining an attacker-supplied request.client_id for validate_grant_type and validate_scopes. A lower-privilege authenticated client can therefore cause grant and scope authorization to use another client's identity when an application validator relies on the documented client_id argument, potentially issuing tokens with unauthorized grants or scopes. Validators that authorize exclusively from request.client may not be affected. This issue is fixed in version 4.0.0.

Record
DEBIAN-CVE-2026-118669
CVSS 4.0
8.4 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:H/SI:H/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Updated
2026-11-04
Show 4 moreShow less
OSVGHSA-7984-qgvg-3j9c 8.4

OAuthLib: Token grants can use attacker-supplied client_id for authorization after authenticating a different client

Summary

OAuthlib's token grant handlers can authenticate one client while authorizing the grant type and requested scopes using a different, attacker-supplied client_id from the request body.

In affected token grant flows, authenticate_client(request) sets request.client to the authenticated client object, but OAuthlib does not require request.client_id to match request.client.client_id. If the request body already contains client_id=..., OAuthlib keeps that value and passes it to validate_grant_type() and validate_scopes().

As a result, an authenticated low-privilege confidential client can authenticate as itself, submit another client's client_id in the token request body, and cause grant and scope validation to run under that other client identity.

Affected Surface

The affected public surface is the OAuth2 token endpoint handling for:

  • client_credentials
  • password / Resource Owner Password Credentials

The issue is relevant to OAuthlib provider deployments where:

  • the attacker has credentials for one valid lower-privilege confidential client;
  • another client has broader grants or scopes;
  • the application validator uses the client_id argument passed by OAuthlib in validate_grant_type() or validate_scopes(), as the RequestValidator API is designed to support.

Deployments whose validators ignore the client_id argument and authorize only from request.client may not be affected.

Details

Request parses query and body parameters into request attributes, including client_id:

The RequestValidator.authenticate_client() contract requires the integrator to authenticate the client and set request.client:

For the client_credentials grant, OAuthlib authenticates the client, verifies that request.client has a client_id, then performs grant and scope validation before normalizing request.client_id from request.client.client_id:

The problematic order is:

if not self.request_validator.authenticate_client(request):
    ...
elif not hasattr(request.client, 'client_id'):
    ...

self.validate_grant_type(request)

request.client_id = request.client_id or request.client.client_id
self.validate_scopes(request)

Because OAuthlib only fills request.client_id when it is missing, an attacker-supplied body value such as client_id=high survives even when request.client.client_id == "low".

The shared grant helper then authorizes using request.client_id, while passing the authenticated client object separately:

The same identity split exists in the Resource Owner Password Credentials flow. After client authentication and user validation, OAuthlib validates the grant and scopes before replacing a missing request.client_id from request.client.client_id:

This creates an…

Record
GHSA-7984-qgvg-3j9c
CVSS 4.0
8.4 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:H/SI:H/SA:N
Weakness
CWE-863
Updated
2026-11-02
OSVROOT-APP-PYPI-CVE-2026-118669 8.4

CVE-2026-118669 in oauthlib - Patched by Root

Root has patched CVE-2026-118669 in the oauthlib package for Root:PyPI. Multiple fixed versions available.

Record
ROOT-APP-PYPI-CVE-2026-118669
CVSS 4.0
8.4 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:H/SI:H/SA:N
Updated
2026-11-06
OSVUBUNTU-CVE-2026-118669 8.4

OAuthLib is an implementation of the OAuth request-signing logic for Python 3.6+. Prior to 4.0.0, the client_credentials and Resource Owner Password Credentials token grant handlers can authenticate request.client as one confidential client while retaining an attacker-supplied request.client_id for validate_grant_type and validate_scopes. A lower-privilege authenticated client can therefore cause grant and scope authorization to use another client's identity when an application validator relies on the documented client_id argument, potentially issuing tokens with unauthorized grants or scopes. Validators that authorize exclusively from request.client may not be affected. This issue is fixed in version 4.0.0.

Record
UBUNTU-CVE-2026-118669
CVSS 4.0
8.4 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:H/SI:H/SA:N
Updated
2026-11-05
OSVAZL-112133 No score

CVE-2026-118669 affecting package python-oauthlib 3.2.2-4

OAuthLib is an implementation of the OAuth request-signing logic for Python 3.6+. Prior to 4.0.0, the client_credentials and Resource Owner Password Credentials token grant handlers can authenticate request.client as one confidential client while retaining an attacker-supplied request.client_id for validate_grant_type and validate_scopes. A lower-privilege authenticated client can therefore cause grant and scope authorization to use another client's identity when an application validator relies on the documented client_id argument, potentially issuing tokens with unauthorized grants or scopes. Validators that authorize exclusively from request.client may not be affected. This issue is fixed in version 4.0.0.

Record
AZL-112133
Updated
2026-11-05

Affected products

Affected packages

Affected packages
PackageAffectedFixed
oauthlib
PyPI
before 4.0.0
4.0.0
python-oauthlib
Azure Linux:3
through 3.2.2-4 None known
python-oauthlib
Debian: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-oauthlib
Debian:13
All versions, plus listed versions
3.2.2-33.2.2-43.3.1-13.3.1-2
None known
python-oauthlib
Debian:14
All versions, plus listed versions
3.2.2-33.2.2-43.3.1-13.3.1-2
None known
oauthlib
PyPI
before 4.0.0, plus listed versions
0.0.10.0.20.1.00.1.10.1.2
Show 45 moreShow less
0.1.30.3.00.3.20.3.30.3.40.3.50.3.60.3.70.3.80.4.00.4.10.4.20.5.00.5.10.6.00.6.10.6.20.6.30.7.00.7.10.7.21.0.01.0.11.0.21.0.31.1.01.1.11.1.22.0.02.0.12.0.22.0.32.0.42.0.52.0.62.0.72.1.03.0.03.0.13.0.23.1.03.1.13.2.03.2.13.2.2
4.0.0
oauthlib
Root:PyPI
before 3.3.1+aikido.2
3.3.1+aikido.23.2.2+aikido.1
python-oauthlib
Ubuntu:16.04:LTS
All versions, plus listed versions
1.0.0-11.0.3-1
None known
python-oauthlib
Ubuntu:18.04:LTS
All versions, plus listed versions
2.0.1-12.0.4-12.0.6-1
None known
python-oauthlib
Ubuntu:20.04:LTS
All versions, plus listed versions
2.1.0-13.1.0-1ubuntu13.1.0-1ubuntu2
None known
Show 4 moreShow less
Affected packages
PackageAffectedFixed
python-oauthlib
Ubuntu: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-oauthlib
Ubuntu:24.04:LTS
All versions, plus listed versions
3.2.2-1
None known
python-oauthlib
Ubuntu:26.10
All versions, plus listed versions
3.3.1-1build13.3.1-2
None known
python-oauthlib
Ubuntu:26.04:LTS
All versions, plus listed versions
3.2.2-33.3.1-13.3.1-1build1
None known

History

History
RecordedChangedSources
affectedOSV
factsEUVD, NVD
referencesCVE List
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-118669 is a high vulnerability (CVSS 8.4) in Oauthlib, published October 28, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.31%, the 24th percentile. Fixed in oauthlib 4.0.0.

References

Show 5 moreShow less
This page doesn't list everything

Left out here: 2 versions and the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open