CVE-2026-116672
Authlib RFC 7592 examples omit registration-access-token client binding
Authlib is a Python library which builds OAuth and OpenID Connect servers. From 0.15 until 1.9.1, the documented ClientConfigurationEndpoint.authenticate_client and ClientConfigurationEndpoint.check_permission reference implementations look up a target client from request-controlled client_id data and check only whether that target is editable, without verifying that request.credential belongs to the target client. Deployments following both examples can allow a client holding any valid registration access token to read, modify, or delete another client's registration. Changing redirect_uris can enable authorization code or token interception, while deleting registrations can deny service to affected clients. This issue is fixed in version 1.9.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
- High
- Integrity
- High
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
8.8
Authlib RFC 7592 examples omit registration-access-token client binding
Authlib is a Python library which builds OAuth and OpenID Connect servers. From 0.15 until 1.9.1, the documented ClientConfigurationEndpoint.authenticate_client and ClientConfigurationEndpoint.check_permission reference implementations look up a target client from request-controlled client_id data and check only whether that target is editable, without verifying that request.credential belongs to the target client. Deployments following both examples can allow a client holding any valid registration access token to read, modify, or delete another client's registration. Changing redirect_uris can enable authorization code or token interception, while deleting registrations can deny service to affected clients. This issue is fixed in version 1.9.1.
- Record
CVE-2026-116672- CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-639, CWE-1188
- Updated
- 2026-11-02
EUVDEUVD-2026-111112
8.8
Authlib is a Python library which builds OAuth and OpenID Connect servers. From 0.15 until 1.9.1, the documented ClientConfigurationEndpoint.authenticate_client and ClientConfigurationEndpoint.check_permission reference implementations look up a target client from request-controlled client_id data and check only whether that target is editable, without verifying that request.credential belongs to the target client. Deployments following both examples can allow a client holding any valid registration access token to read, modify, or delete another client's registration. Changing redirect_uris can enable authorization code or token interception, while deleting registrations can deny service to affected clients. This issue is fixed in version 1.9.1.
- Record
EUVD-2026-111112- CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-c73q-w75p-j82v
8.8
Authlib RFC 7592 examples omit registration-access-token client binding
Description
Summary
RFC 7592 (OAuth 2.0 Dynamic Client Registration Management Protocol) lets a previously registered client read, update, or delete its own registration, authenticated by a registration_access_token issued specifically to that client at registration time. The entire security model of this protocol depends on the server verifying that the token presented in the request actually belongs to the client identified in the request, not merely that the token is valid for some client.
Authlib's ClientConfigurationEndpoint implements the control flow correctly in structure, calling authenticate_token, then authenticate_client, then check_permission, and treats all three as abstract methods that "Developers MUST implement in subclass." The problem is that the documented example implementations for these methods, taken together exactly as written, never perform the one check that matters: binding the authenticated token to the specific client being accessed. A developer who implements these methods by following the provided examples ends up with a complete authorization bypass on this endpoint.
Details
authenticate_client's documented example (authlib/oauth2/rfc7592/endpoint.py):
def authenticate_client(self, request):
"""Read a client from the request payload.
Developers MUST implement this method in subclass::
def authenticate_client(self, request):
client_id = request.payload.data.get("client_id")
return Client.get(client_id=client_id)
:return: client instance
"""
raise NotImplementedError()
This looks the target client up purely by the client_id supplied in the request payload, with no reference to the token at all.
check_permission's documented example, in the same file:
def check_permission(self, client, request):
"""Checks whether the current client is allowed to be accessed, edited
or deleted. Developers MUST implement it in subclass, e.g.::
def check_permission(self, client, request):
return client.editable
:return: boolean
"""
raise NotImplementedError()
This checks a property of the target client alone (whether it is generally "editable"), again with no reference to request.credential, the authenticated token object returned earlier by authenticate_token and stored on the request specifically so that later steps can check it:
def create_configuration_response(self, request):
token = self.authenticate_token(request)
if not token:
raise AccessDeniedError()
request.credential = token
client = self.authenticate_client(request)
...
if not self.check_permission(client, request):
raise UnauthorizedClientError(...)
request.credential is set specifically so that a binding check can be performed downstream, but neither documented example ever reads it. Following both examples as written produces an implementation where the only requirements to access, modify, or delete a client's registration are: possessing any valid registration_access_token for any client, and knowing or guessing the target client_id.
This is meaningfully different from how the equivalent example is written for the token introspection endpoint (RFC 7662) elsewhere in the same codebase, which does correctly demonstrate checking the authenticated caller's own identity (authlib/oauth2/rfc7662/introspection.py):
def check_permission(self, token, client, request):
"""Check if the request has permission to introspect the token. Developers
MUST implement this method::
def check_permission(self, token, client, request):
# only allow a special client to introspect the token
return client.client_id == "introspection_client"
"""
In that endpoint, client represents the already-authenticated caller (verified through normal client credential authentication earlier in the…
- Record
GHSA-c73q-w75p-j82v- CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-639, CWE-1188
- Updated
- 2026-11-02
NVD
8.8
Authlib is a Python library which builds OAuth and OpenID Connect servers. From 0.15 until 1.9.1, the documented ClientConfigurationEndpoint.authenticate_client and ClientConfigurationEndpoint.check_permission reference implementations look up a target client from request-controlled client_id data and check only whether that target is editable, without verifying that request.credential belongs to the target client. Deployments following both examples can allow a client holding any valid registration access token to read, modify, or delete another client's registration. Changing redirect_uris can enable authorization code or token interception, while deleting registrations can deny service to affected clients. This issue is fixed in version 1.9.1.
- Record
CVE-2026-116672- CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-639, CWE-1188
- Updated
- 2026-11-02
OSV
8.8
Authlib RFC 7592 examples omit registration-access-token client binding
Authlib is a Python library which builds OAuth and OpenID Connect servers. From 0.15 until 1.9.1, the documented ClientConfigurationEndpoint.authenticate_client and ClientConfigurationEndpoint.check_permission reference implementations look up a target client from request-controlled client_id data and check only whether that target is editable, without verifying that request.credential belongs to the target client. Deployments following both examples can allow a client holding any valid registration access token to read, modify, or delete another client's registration. Changing redirect_uris can enable authorization code or token interception, while deleting registrations can deny service to affected clients. This issue is fixed in version 1.9.1.
- Record
CVE-2026-116672- CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-1188, CWE-639
- Updated
- 2026-11-03
OSVDEBIAN-CVE-2026-116672
8.8
Authlib is a Python library which builds OAuth and OpenID Connect servers. From 0.15 until 1.9.1, the documented ClientConfigurationEndpoint.authenticate_client and ClientConfigurationEndpoint.check_permission reference implementations look up a target client from request-controlled client_id data and check only whether that target is editable, without verifying that request.credential belongs to the target client. Deployments following both examples can allow a client holding any valid registration access token to read, modify, or delete another client's registration. Changing redirect_uris can enable authorization code or token interception, while deleting registrations can deny service to affected clients. This issue is fixed in version 1.9.1.
- Record
DEBIAN-CVE-2026-116672- CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Updated
- 2026-11-02
OSVGHSA-c73q-w75p-j82v
8.8
Authlib RFC 7592 examples omit registration-access-token client binding
Description
Summary
RFC 7592 (OAuth 2.0 Dynamic Client Registration Management Protocol) lets a previously registered client read, update, or delete its own registration, authenticated by a registration_access_token issued specifically to that client at registration time. The entire security model of this protocol depends on the server verifying that the token presented in the request actually belongs to the client identified in the request, not merely that the token is valid for some client.
Authlib's ClientConfigurationEndpoint implements the control flow correctly in structure, calling authenticate_token, then authenticate_client, then check_permission, and treats all three as abstract methods that "Developers MUST implement in subclass." The problem is that the documented example implementations for these methods, taken together exactly as written, never perform the one check that matters: binding the authenticated token to the specific client being accessed. A developer who implements these methods by following the provided examples ends up with a complete authorization bypass on this endpoint.
Details
authenticate_client's documented example (authlib/oauth2/rfc7592/endpoint.py):
def authenticate_client(self, request):
"""Read a client from the request payload.
Developers MUST implement this method in subclass::
def authenticate_client(self, request):
client_id = request.payload.data.get("client_id")
return Client.get(client_id=client_id)
:return: client instance
"""
raise NotImplementedError()
This looks the target client up purely by the client_id supplied in the request payload, with no reference to the token at all.
check_permission's documented example, in the same file:
def check_permission(self, client, request):
"""Checks whether the current client is allowed to be accessed, edited
or deleted. Developers MUST implement it in subclass, e.g.::
def check_permission(self, client, request):
return client.editable
:return: boolean
"""
raise NotImplementedError()
This checks a property of the target client alone (whether it is generally "editable"), again with no reference to request.credential, the authenticated token object returned earlier by authenticate_token and stored on the request specifically so that later steps can check it:
def create_configuration_response(self, request):
token = self.authenticate_token(request)
if not token:
raise AccessDeniedError()
request.credential = token
client = self.authenticate_client(request)
...
if not self.check_permission(client, request):
raise UnauthorizedClientError(...)
request.credential is set specifically so that a binding check can be performed downstream, but neither documented example ever reads it. Following both examples as written produces an implementation where the only requirements to access, modify, or delete a client's registration are: possessing any valid registration_access_token for any client, and knowing or guessing the target client_id.
This is meaningfully different from how the equivalent example is written for the token introspection endpoint (RFC 7662) elsewhere in the same codebase, which does correctly demonstrate checking the authenticated caller's own identity (authlib/oauth2/rfc7662/introspection.py):
def check_permission(self, token, client, request):
"""Check if the request has permission to introspect the token. Developers
MUST implement this method::
def check_permission(self, token, client, request):
# only allow a special client to introspect the token
return client.client_id == "introspection_client"
"""
In that endpoint, client represents the already-authenticated caller (verified through normal client credential authentication earlier in the…
- Record
GHSA-c73q-w75p-j82v- CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-1188, CWE-639
- Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-116672
8.8
Authlib is a Python library which builds OAuth and OpenID Connect servers. From 0.15 until 1.9.1, the documented ClientConfigurationEndpoint.authenticate_client and ClientConfigurationEndpoint.check_permission reference implementations look up a target client from request-controlled client_id data and check only whether that target is editable, without verifying that request.credential belongs to the target client. Deployments following both examples can allow a client holding any valid registration access token to read, modify, or delete another client's registration. Changing redirect_uris can enable authorization code or token interception, while deleting registrations can deny service to affected clients. This issue is fixed in version 1.9.1.
- Record
UBUNTU-CVE-2026-116672- CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Updated
- 2026-11-02
OSVopenSUSE-SU-2026:12390-1 No score
python313-Authlib-1.9.1-1.1 on GA media
These are all security issues fixed in the python313-Authlib-1.9.1-1.1 package on the GA media of openSUSE Tumbleweed.
- Record
openSUSE-SU-2026:12390-1- Updated
- 2026-11-03
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
authlibPyPI |
0.15 to 1.9.0 | 1.9.1 |
python-authlibDebian:12 |
All versions, plus listed versions 1.2.0-11.2.0-1+deb12u11.2.0-1+deb12u21.2.1-11.3.0-1 Show 23 moreShow less1.3.0-21.3.0-31.3.1-11.3.2-11.3.2-21.4.0-11.4.1-11.5.0-11.5.1-11.5.2-11.6.0-11.6.1-11.6.3-11.6.4-11.6.5-11.6.6-11.6.7-11.6.8-11.6.9-11.7.0-11.7.2-11.7.2-21.9.1-1 |
None known |
python-authlibDebian:13 |
All versions, plus listed versions 1.6.0-11.6.0-1+deb13u11.6.1-11.6.3-11.6.4-1 Show 9 moreShow less1.6.5-11.6.6-11.6.7-11.6.8-11.6.9-11.7.0-11.7.2-11.7.2-21.9.1-1 |
None known |
python-authlibDebian:14 |
before 1.9.1-1, plus listed versions 1.6.0-11.6.1-11.6.3-11.6.4-11.6.5-1 Show 7 moreShow less1.6.6-11.6.7-11.6.8-11.6.9-11.7.0-11.7.2-11.7.2-2 |
1.9.1-1 |
authlibPyPI |
0.15 up to 1.9.1, plus listed versions 0.15.10.15.20.15.30.15.40.15.5 Show 37 moreShow less0.15.61.0.01.0.0a11.0.0a21.0.0b11.0.0b21.0.0rc11.0.11.1.01.2.01.2.11.3.01.3.11.3.21.4.01.4.11.5.01.5.11.5.21.6.01.6.11.6.101.6.111.6.121.6.21.6.31.6.41.6.51.6.61.6.71.6.81.6.91.7.01.7.11.7.21.8.01.9.0 |
1.9.1 |
python-authlibUbuntu:Pro:22.04:LTS |
All versions, plus listed versions 0.15.4-10.15.5-10.15.5-1ubuntu0.1~esm10.15.5-1ubuntu0.1~esm2 |
None known |
python-authlibUbuntu:Pro:24.04:LTS |
All versions, plus listed versions 1.2.1-11.3.0-11.3.0-1ubuntu0.1~esm11.3.0-1ubuntu0.1~esm2 |
None known |
python-authlibUbuntu:26.10 |
All versions, plus listed versions 1.6.7-11.7.2-11.7.2-2 |
None known |
python-authlibUbuntu:Pro:26.04:LTS |
All versions, plus listed versions 1.6.0-11.6.5-11.6.6-11.6.7-11.6.7-1ubuntu0.1~esm1 |
None known |
python-AuthlibopenSUSE:Tumbleweed From an advisory covering 10 CVEs |
before 1.9.1-1.1 | 1.9.1-1.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected | ||
| affected, aliases, facts, references | OSV | |
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-116672 is a high vulnerability (CVSS 8.8) in Authlib, published October 27, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.27%, the 19th percentile. Fixed in authlib 1.9.1.
References
github.com/authlib/authlib/security/advisories/GHSA-c73q-w75p-j82v
github.com/authlib/authlib/commit/1bd2a313492ce0a4d0571c150730907aa3fc91ff
github.com/authlib/authlib/releases/tag/v1.9.1
nvd.nist.gov/vuln/detail/CVE-2026-116672
github.com/advisories/GHSA-c73q-w75p-j82v
github.com/CVEProject/cvelistV5/tree/main/cves/2026/116xxx/CVE-2026-116672.json
Show 14 moreShow less
security-tracker.debian.org/tracker/CVE-2026-116672
github.com/authlib/authlib
ubuntu.com/security/CVE-2026-116672
cve.org/CVERecord?id=CVE-2026-116672
suse.com/security/cve/CVE-2025-62706
suse.com/security/cve/CVE-2026-114614
suse.com/security/cve/CVE-2026-114615
suse.com/security/cve/CVE-2026-114616
suse.com/security/cve/CVE-2026-114617
suse.com/security/cve/CVE-2026-114618
suse.com/security/cve/CVE-2026-114619
suse.com/security/cve/CVE-2026-116672
suse.com/security/cve/CVE-2026-41425
suse.com/security/cve/CVE-2026-96760
Left out here: the rest of 2 source descriptions. The JSON record has them.