CVE-2026-48523
PyJWT: Algorithm allow-list bypass when decoding with `PyJWK` / `PyJWKClient` keys
PyJWT is a JSON Web Token implementation in Python. From 2.9.0 to 2.12.1, there is a verifier-side algorithm allow-list bypass when jwt.decode() or jwt.decode_complete() are called with a PyJWK key. The token header alg is checked against the caller-supplied algorithms allow-list, but signature verification is performed with the algorithm bound to the PyJWK object instead of the header algorithm. An attacker who controls a registered JWK/JWKS private key can sign with a disallowed algorithm, advertise an allowed algorithm in the JWT header, and still be accepted. The issue affects the documented PyJWKClient.get_signing_key_from_jwt(...) flow. This vulnerability is fixed in 2.13.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
- Low
- Integrity
- Low
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
5.4
PyJWT: Algorithm allow-list bypass when decoding with `PyJWK` / `PyJWKClient` keys
PyJWT is a JSON Web Token implementation in Python. From 2.9.0 to 2.12.1, there is a verifier-side algorithm allow-list bypass when jwt.decode() or jwt.decode_complete() are called with a PyJWK key. The token header alg is checked against the caller-supplied algorithms allow-list, but signature verification is performed with the algorithm bound to the PyJWK object instead of the header algorithm. An attacker who controls a registered JWK/JWKS private key can sign with a disallowed algorithm, advertise an allowed algorithm in the JWT header, and still be accepted. The issue affects the documented PyJWKClient.get_signing_key_from_jwt(...) flow. This vulnerability is fixed in 2.13.0.
- Record
CVE-2026-48523- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N - Weakness
- CWE-347
- Updated
- 2026-11-02
EUVDEUVD-2026-32918
5.4
PyJWT is a JSON Web Token implementation in Python. From 2.9.0 to 2.12.1, there is a verifier-side algorithm allow-list bypass when jwt.decode() or jwt.decode_complete() are called with a PyJWK key. The token header alg is checked against the caller-supplied algorithms allow-list, but signature verification is performed with the algorithm bound to the PyJWK object instead of the header algorithm. An attacker who controls a registered JWK/JWKS private key can sign with a disallowed algorithm, advertise an allowed algorithm in the JWT header, and still be accepted. The issue affects the documented PyJWKClient.get_signing_key_from_jwt(...) flow. This vulnerability is fixed in 2.13.0.
- Record
EUVD-2026-32918- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-jq35-7prp-9v3f
5.4
PyJWT: Algorithm allow-list bypass when decoding with `PyJWK` / `PyJWKClient` keys
[!NOTE] Scored assuming a deployment where algorithm policy functions as an authentication/authorization boundary. In deployments where the algorithm policy enforces crypto agility only, the practical confidentiality impact is lower and the issue is closer to an integrity-of-policy-enforcement bug.
PyJWT 2.9.0 through 2.12.1 allows a verifier-side algorithm allow-list bypass when jwt.decode() or jwt.decode_complete() are called with a PyJWK key. The token header alg is checked against the caller-supplied algorithms allow-list, but signature verification is performed with the algorithm bound to the PyJWK object instead of the header algorithm. An attacker who controls a registered JWK/JWKS private key can sign with a disallowed algorithm, advertise an allowed algorithm in the JWT header, and still be accepted. The issue affects the documented PyJWKClient.get_signing_key_from_jwt(...) flow.
Summary
PyJWT's PyJWK verification path allows a verifier-side algorithm allow-list bypass.
In affected versions, when a JWT is decoded with a PyJWK object, PyJWT verifies that the header alg string is present in the caller's algorithms=[...] list, but it does not actually use the header algorithm to verify the signature. Instead, it verifies with the algorithm already bound to the PyJWK object.
This lets an attacker who controls a registered JWK/JWKS private key sign with a disallowed algorithm and have the token accepted as long as the JWT header advertises an allowed algorithm. This affects the documented PyJWKClient usage flow and does not require any non-default flags or unsafe configuration.
Details
In jwt/api_jws.py in 2.12.1, _verify_signature() treats PyJWK keys differently from normal PEM/public-key inputs:
if algorithms is None and isinstance(key, PyJWK):
algorithms = [key.algorithm_name]
...
if not alg or (algorithms is not None and alg not in algorithms):
raise InvalidAlgorithmError("The specified alg value is not allowed")
if isinstance(key, PyJWK):
alg_obj = key.Algorithm
prepared_key = key.key
else:
alg_obj = self.get_algorithm_by_name(alg)
prepared_key = alg_obj.prepare_key(key)
This logic means:
- The JWT header
algis checked only as a string against the caller-supplied allow-list. - If the key is a
PyJWK, the actual verifier is not selected from the header algorithm. - Instead, PyJWT always verifies with
key.Algorithm, which is fixed when thePyJWKobject is created.
PyJWK binds its algorithm in jwt/api_jwk.py from the JWK's alg field or from key-type defaults:
if not algorithm and isinstance(self._jwk_data, dict):
algorithm = self._jwk_data.get("alg", None)
...
self.algorithm_name = algorithm
self.Algorithm = get_default_algorithms()[algorithm]
self.key = self.Algorithm.from_jwk(self._jwk_data)
So once a PyJWK is constructed, the verifier uses the PyJWK's bound algorithm, not the JWT header algorithm.
The issue is reachable through the documented JWKS flow. In docs/usage.rst, the project documents:
signing_key = jwks_client.get_signing_key_from_jwt(token)
jwt.decode(
token,
signing_key,
audience="https://expenses-api",
options={"verify_exp": False},
algorithms=["RS256"],
)
PyJWKClient.get_signing_key_from_jwt() returns a PyJWK, so this documented path is affected.
This is not a "no-key forgery" issue. The attacker still needs control of an accepted JWK/JWKS private key. However, that is realistic in deployments such as:
- self-service OAuth client assertions
- multi-tenant key registration
- federation / BYO-JWKS trust models
- any system where external parties sign JWTs with their own registered keys
In those cases, the attacker can bypass verifier-side algorithm policy. For example, if the server intends to only accept PS256, an attacker controlling an accepted RSA JWK can sign with RS256, set alg=PS256 in the JWT header, and…
- Record
GHSA-jq35-7prp-9v3f- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N - Weakness
- CWE-347
- Updated
- 2026-11-02
NVD
5.4
PyJWT is a JSON Web Token implementation in Python. From 2.9.0 to 2.12.1, there is a verifier-side algorithm allow-list bypass when jwt.decode() or jwt.decode_complete() are called with a PyJWK key. The token header alg is checked against the caller-supplied algorithms allow-list, but signature verification is performed with the algorithm bound to the PyJWK object instead of the header algorithm. An attacker who controls a registered JWK/JWKS private key can sign with a disallowed algorithm, advertise an allowed algorithm in the JWT header, and still be accepted. The issue affects the documented PyJWKClient.get_signing_key_from_jwt(...) flow. This vulnerability is fixed in 2.13.0.
- Record
CVE-2026-48523- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N - Weakness
- CWE-347
- Updated
- 2026-11-02
OSVBELL-CVE-2026-48523
5.4
- Record
BELL-CVE-2026-48523- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N - Updated
- 2026-11-02
OSV
5.4
PyJWT: Algorithm allow-list bypass when decoding with `PyJWK` / `PyJWKClient` keys
PyJWT is a JSON Web Token implementation in Python. From 2.9.0 to 2.12.1, there is a verifier-side algorithm allow-list bypass when jwt.decode() or jwt.decode_complete() are called with a PyJWK key. The token header alg is checked against the caller-supplied algorithms allow-list, but signature verification is performed with the algorithm bound to the PyJWK object instead of the header algorithm. An attacker who controls a registered JWK/JWKS private key can sign with a disallowed algorithm, advertise an allowed algorithm in the JWT header, and still be accepted. The issue affects the documented PyJWKClient.get_signing_key_from_jwt(...) flow. This vulnerability is fixed in 2.13.0.
- Record
CVE-2026-48523- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N - Weakness
- CWE-347
- Updated
- 2026-11-02
Show 15 moreShow less
OSVDEBIAN-CVE-2026-48523
5.4
PyJWT is a JSON Web Token implementation in Python. From 2.9.0 to 2.12.1, there is a verifier-side algorithm allow-list bypass when jwt.decode() or jwt.decode_complete() are called with a PyJWK key. The token header alg is checked against the caller-supplied algorithms allow-list, but signature verification is performed with the algorithm bound to the PyJWK object instead of the header algorithm. An attacker who controls a registered JWK/JWKS private key can sign with a disallowed algorithm, advertise an allowed algorithm in the JWT header, and still be accepted. The issue affects the documented PyJWKClient.get_signing_key_from_jwt(...) flow. This vulnerability is fixed in 2.13.0.
- Record
DEBIAN-CVE-2026-48523- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N - Updated
- 2026-11-02
OSVGHSA-jq35-7prp-9v3f
5.4
PyJWT: Algorithm allow-list bypass when decoding with `PyJWK` / `PyJWKClient` keys
[!NOTE] Scored assuming a deployment where algorithm policy functions as an authentication/authorization boundary. In deployments where the algorithm policy enforces crypto agility only, the practical confidentiality impact is lower and the issue is closer to an integrity-of-policy-enforcement bug.
PyJWT 2.9.0 through 2.12.1 allows a verifier-side algorithm allow-list bypass when jwt.decode() or jwt.decode_complete() are called with a PyJWK key. The token header alg is checked against the caller-supplied algorithms allow-list, but signature verification is performed with the algorithm bound to the PyJWK object instead of the header algorithm. An attacker who controls a registered JWK/JWKS private key can sign with a disallowed algorithm, advertise an allowed algorithm in the JWT header, and still be accepted. The issue affects the documented PyJWKClient.get_signing_key_from_jwt(...) flow.
Summary
PyJWT's PyJWK verification path allows a verifier-side algorithm allow-list bypass.
In affected versions, when a JWT is decoded with a PyJWK object, PyJWT verifies that the header alg string is present in the caller's algorithms=[...] list, but it does not actually use the header algorithm to verify the signature. Instead, it verifies with the algorithm already bound to the PyJWK object.
This lets an attacker who controls a registered JWK/JWKS private key sign with a disallowed algorithm and have the token accepted as long as the JWT header advertises an allowed algorithm. This affects the documented PyJWKClient usage flow and does not require any non-default flags or unsafe configuration.
Details
In jwt/api_jws.py in 2.12.1, _verify_signature() treats PyJWK keys differently from normal PEM/public-key inputs:
if algorithms is None and isinstance(key, PyJWK):
algorithms = [key.algorithm_name]
...
if not alg or (algorithms is not None and alg not in algorithms):
raise InvalidAlgorithmError("The specified alg value is not allowed")
if isinstance(key, PyJWK):
alg_obj = key.Algorithm
prepared_key = key.key
else:
alg_obj = self.get_algorithm_by_name(alg)
prepared_key = alg_obj.prepare_key(key)
This logic means:
- The JWT header
algis checked only as a string against the caller-supplied allow-list. - If the key is a
PyJWK, the actual verifier is not selected from the header algorithm. - Instead, PyJWT always verifies with
key.Algorithm, which is fixed when thePyJWKobject is created.
PyJWK binds its algorithm in jwt/api_jwk.py from the JWK's alg field or from key-type defaults:
if not algorithm and isinstance(self._jwk_data, dict):
algorithm = self._jwk_data.get("alg", None)
...
self.algorithm_name = algorithm
self.Algorithm = get_default_algorithms()[algorithm]
self.key = self.Algorithm.from_jwk(self._jwk_data)
So once a PyJWK is constructed, the verifier uses the PyJWK's bound algorithm, not the JWT header algorithm.
The issue is reachable through the documented JWKS flow. In docs/usage.rst, the project documents:
signing_key = jwks_client.get_signing_key_from_jwt(token)
jwt.decode(
token,
signing_key,
audience="https://expenses-api",
options={"verify_exp": False},
algorithms=["RS256"],
)
PyJWKClient.get_signing_key_from_jwt() returns a PyJWK, so this documented path is affected.
This is not a "no-key forgery" issue. The attacker still needs control of an accepted JWK/JWKS private key. However, that is realistic in deployments such as:
- self-service OAuth client assertions
- multi-tenant key registration
- federation / BYO-JWKS trust models
- any system where external parties sign JWTs with their own registered keys
In those cases, the attacker can bypass verifier-side algorithm policy. For example, if the server intends to only accept PS256, an attacker controlling an accepted RSA JWK can sign with RS256, set alg=PS256 in the JWT header, and…
- Record
GHSA-jq35-7prp-9v3f- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N - Weakness
- CWE-347
- Updated
- 2026-11-02
OSVPYSEC-2026-176
5.4
PyJWT is a JSON Web Token implementation in Python. From 2.9.0 to 2.12.1, there is a verifier-side algorithm allow-list bypass when jwt.decode() or jwt.decode_complete() are called with a PyJWK key. The token header alg is checked against the caller-supplied algorithms allow-list, but signature verification is performed with the algorithm bound to the PyJWK object instead of the header algorithm. An attacker who controls a registered JWK/JWKS private key can sign with a disallowed algorithm, advertise an allowed algorithm in the JWT header, and still be accepted. The issue affects the documented PyJWKClient.get_signing_key_from_jwt(...) flow. This vulnerability is fixed in 2.13.0.
- Record
PYSEC-2026-176- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N - Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-48523
5.4
PyJWT is a JSON Web Token implementation in Python. From 2.9.0 to 2.12.1, there is a verifier-side algorithm allow-list bypass when jwt.decode() or jwt.decode_complete() are called with a PyJWK key. The token header alg is checked against the caller-supplied algorithms allow-list, but signature verification is performed with the algorithm bound to the PyJWK object instead of the header algorithm. An attacker who controls a registered JWK/JWKS private key can sign with a disallowed algorithm, advertise an allowed algorithm in the JWT header, and still be accepted. The issue affects the documented PyJWKClient.get_signing_key_from_jwt(...) flow. This vulnerability is fixed in 2.13.0.
- Record
UBUNTU-CVE-2026-48523- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N - Updated
- 2026-11-02
OSVCLSA-2026-1783299703 No score
TuxCare security update for pyjwt (4 CVEs)
TuxCare rebuilt pyjwt to address 4 CVEs. Fixed in 2.10.1.post2+tuxcare.
- Record
CLSA-2026-1783299703- Updated
- 2026-11-02
OSVopenSUSE-SU-2026:11024-1 No score
python311-PyJWT-2.13.0-1.1 on GA media
These are all security issues fixed in the python311-PyJWT-2.13.0-1.1 package on the GA media of openSUSE Tumbleweed.
- Record
openSUSE-SU-2026:11024-1- Updated
- 2026-11-02
OSVopenSUSE-SU-2026:21095-1 No score
Security update for python-PyJWT
This update for python-PyJWT fixes the following issues
- CVE-2026-48522:
PyJWKClientpasses URI arguments directly tourllib.request.urlopen()and allows for SSRF and token forgery (bsc#1266798). - CVE-2026-48523: verifier-side algorithm allow-list bypass when
jwt.decode()orjwt.decode_complete()are called with a PyJWK key (bsc#1266799). - CVE-2026-48524: unlimited processing of JWTs with unknown kid values by
PyJWKClient.get_signing_key()leads to unbounded JWKS endpoint requests and DoS (bsc#1266800). - CVE-2026-48525: unbounded Base64URL decoding of unused payload segment in
b64=falsedetached JWS allows for DoS (bsc#1266801). - CVE-2026-48526: no validation of use of JSON Web Keys in HMAC algorithm when decoding JSON Web Tokens allows for forged HS256 tokens (bsc#1266802).
- Record
openSUSE-SU-2026:21095-1- Updated
- 2026-11-02
OSVROOT-APP-PYPI-CVE-2026-48523 No score
CVE-2026-48523 in PyJWT - Patched by Root
Root has patched CVE-2026-48523 in the PyJWT package for Root:PyPI. Multiple fixed versions available.
- Record
ROOT-APP-PYPI-CVE-2026-48523- Updated
- 2026-11-02
OSVSUSE-SU-2026:22138-1 No score
Security update for python-PyJWT
This update for python-PyJWT fixes the following issues
- CVE-2026-48522:
PyJWKClientpasses URI arguments directly tourllib.request.urlopen()and allows for SSRF and token forgery (bsc#1266798). - CVE-2026-48523: verifier-side algorithm allow-list bypass when
jwt.decode()orjwt.decode_complete()are called with a PyJWK key (bsc#1266799). - CVE-2026-48524: unlimited processing of JWTs with unknown kid values by
PyJWKClient.get_signing_key()leads to unbounded JWKS endpoint requests and DoS (bsc#1266800). - CVE-2026-48525: unbounded Base64URL decoding of unused payload segment in
b64=falsedetached JWS allows for DoS (bsc#1266801). - CVE-2026-48526: no validation of use of JSON Web Keys in HMAC algorithm when decoding JSON Web Tokens allows for forged HS256 tokens (bsc#1266802).
- Record
SUSE-SU-2026:22138-1- Updated
- 2026-11-02
OSVSUSE-SU-2026:22170-1 No score
Security update for python-PyJWT
This update for python-PyJWT fixes the following issues
- CVE-2026-48522:
PyJWKClientpasses URI arguments directly tourllib.request.urlopen()and allows for SSRF and token forgery (bsc#1266798). - CVE-2026-48523: verifier-side algorithm allow-list bypass when
jwt.decode()orjwt.decode_complete()are called with a PyJWK key (bsc#1266799). - CVE-2026-48524: unlimited processing of JWTs with unknown kid values by
PyJWKClient.get_signing_key()leads to unbounded JWKS endpoint requests and DoS (bsc#1266800). - CVE-2026-48525: unbounded Base64URL decoding of unused payload segment in
b64=falsedetached JWS allows for DoS (bsc#1266801). - CVE-2026-48526: no validation of use of JSON Web Keys in HMAC algorithm when decoding JSON Web Tokens allows for forged HS256 tokens (bsc#1266802).
- Record
SUSE-SU-2026:22170-1- Updated
- 2026-11-02
OSVSUSE-SU-2026:22220-1 No score
Security update for python-PyJWT
This update for python-PyJWT fixes the following issues
- CVE-2026-48522:
PyJWKClientpasses URI arguments directly tourllib.request.urlopen()and allows for SSRF and token forgery (bsc#1266798). - CVE-2026-48523: verifier-side algorithm allow-list bypass when
jwt.decode()orjwt.decode_complete()are called with a PyJWK key (bsc#1266799). - CVE-2026-48524: unlimited processing of JWTs with unknown kid values by
PyJWKClient.get_signing_key()leads to unbounded JWKS endpoint requests and DoS (bsc#1266800). - CVE-2026-48525: unbounded Base64URL decoding of unused payload segment in
b64=falsedetached JWS allows for DoS (bsc#1266801). - CVE-2026-48526: no validation of use of JSON Web Keys in HMAC algorithm when decoding JSON Web Tokens allows for forged HS256 tokens (bsc#1266802).
- Record
SUSE-SU-2026:22220-1- Updated
- 2026-11-02
OSVSUSE-SU-2026:22238-1 No score
Security update for python-PyJWT
This update for python-PyJWT fixes the following issues
- CVE-2026-48522:
PyJWKClientpasses URI arguments directly tourllib.request.urlopen()and allows for SSRF and token forgery (bsc#1266798). - CVE-2026-48523: verifier-side algorithm allow-list bypass when
jwt.decode()orjwt.decode_complete()are called with a PyJWK key (bsc#1266799). - CVE-2026-48524: unlimited processing of JWTs with unknown kid values by
PyJWKClient.get_signing_key()leads to unbounded JWKS endpoint requests and DoS (bsc#1266800). - CVE-2026-48525: unbounded Base64URL decoding of unused payload segment in
b64=falsedetached JWS allows for DoS (bsc#1266801). - CVE-2026-48526: no validation of use of JSON Web Keys in HMAC algorithm when decoding JSON Web Tokens allows for forged HS256 tokens (bsc#1266802).
- Record
SUSE-SU-2026:22238-1- Updated
- 2026-11-02
OSVSUSE-SU-2026:2626-1 No score
Security update for python-PyJWT
This update for python-PyJWT fixes the following issues
- CVE-2026-48522:
PyJWKClientpasses URI arguments directly tourllib.request.urlopen()and allows for SSRF and token forgery (bsc#1266798). - CVE-2026-48523: verifier-side algorithm allow-list bypass when
jwt.decode()orjwt.decode_complete()are called with a PyJWK key (bsc#1266799). - CVE-2026-48524: unlimited processing of JWTs with unknown kid values by
PyJWKClient.get_signing_key()leads to unbounded JWKS endpoint requests and DoS (bsc#1266800). - CVE-2026-48525: unbounded Base64URL decoding of unused payload segment in
b64=falsedetached JWS allows for DoS (bsc#1266801). - CVE-2026-48526: no validation of use of JSON Web Keys in HMAC algorithm when decoding JSON Web Tokens allows for forged HS256 tokens (bsc#1266802).
- Record
SUSE-SU-2026:2626-1- Updated
- 2026-11-02
OSVSUSE-SU-2026:2627-1 No score
Security update for python-PyJWT
This update for python-PyJWT fixes the following issues
- CVE-2026-48522:
PyJWKClientpasses URI arguments directly tourllib.request.urlopen()and allows for SSRF and token forgery (bsc#1266798). - CVE-2026-48523: verifier-side algorithm allow-list bypass when
jwt.decode()orjwt.decode_complete()are called with a PyJWK key (bsc#1266799). - CVE-2026-48525: unbounded Base64URL decoding of unused payload segment in
b64=falsedetached JWS allows for DoS (bsc#1266801). - CVE-2026-48526: no validation of use of JSON Web Keys in HMAC algorithm when decoding JSON Web Tokens allows for forged HS256 tokens (bsc#1266802).
- Record
SUSE-SU-2026:2627-1- Updated
- 2026-11-02
OSVUSN-8823-1 No score
pyjwt vulnerabilities
It was discovered that PyJWT incorrectly handled certain URIs when using PyJWKClient. A remote attacker could possibly use this issue to perform server-side request forgery (SSRF) or expose sensitive local files. This issue only affected Ubuntu 22.04 LTS, Ubuntu 24.04 LTS and Ubuntu 26.04 LTS. (CVE-2026-48522)
It was discovered that PyJWT incorrectly verified cryptographic signatures when decoding tokens with PyJWK keys. A remote attacker could possibly use this issue to bypass signature verification and forge valid JSON Web Tokens. This issue only affected Ubuntu 26.04 LTS. (CVE-2026-48523)
It was discovered that PyJWT incorrectly handled unknown key identifiers in PyJWKClient. A remote attacker could possibly use this issue to cause PyJWT to make excessive network requests, resulting in a denial of service. This issue only affected Ubuntu 24.04 LTS and Ubuntu 26.04 LTS. (CVE-2026-48524)
It was discovered that PyJWT incorrectly handled payload decoding during detached JWS token verification. A remote attacker could possibly use this issue to cause PyJWT to consume excessive resources, resulting in a denial of service. This issue only affected Ubuntu 24.04 LTS and Ubuntu 26.04 LTS. (CVE-2026-48525)
It was discovered that PyJWT incorrectly validated JSON Web Keys when decoding tokens with both HMAC and asymmetric algorithms enabled. A remote attacker could possibly use this issue to forge valid tokens, resulting in an authentication bypass. (CVE-2026-48526)
- Record
USN-8823-1- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
pyjwtPyPI |
2.9.0 up to 2.13.0 | 2.13.0 |
py3-jwtAlpaquita:25 |
2.10.1-r0 up to 2.13.0-r0 | 2.13.0-r0 |
py3-jwtAlpaquita:stream |
2.8.0-r1 up to 2.13.0-r0 | 2.13.0-r0 |
pyjwtTuxCare:PyPI From an advisory covering 4 CVEs |
2.10.1 up to 2.10.1.post2+tuxcare, plus listed versions 2.10.1.post1+tuxcare |
2.10.1.post2+tuxcare |
pyjwtDebian:13 |
All versions, plus listed versions 2.10.1-22.10.1-2+deb13u12.10.1-32.10.1-42.11.0-2 Show 5 moreShow less2.12.1-12.13.0-12.14.0-12.15.0-12.15.1-1 |
None known |
pyjwtDebian:14 |
before 2.13.0-1, plus listed versions 2.10.1-22.10.1-32.10.1-42.11.0-22.12.1-1 |
2.13.0-1 |
pyjwtPyPI |
2.9.0 up to 2.13.0, plus listed versions 2.10.02.10.12.11.02.12.02.12.1 |
2.13.0 |
pyjwtPyPI |
2.9.0 up to 2.12.1, plus listed versions 2.10.02.10.12.11.02.12.0 |
2.12.1 |
PyJWTRoot:PyPI |
before 2.9.0+aikido.6 | 2.9.0+aikido.62.10.1+aikido.62.12.0+aikido.32.12.1+aikido.32.10.1+aikido.72.12.0+aikido.42.12.0+aikido.52.12.1+aikido.42.12.1+aikido.5 |
python-PyJWTSUSE:Linux Micro 6.1 From an advisory covering 5 CVEs |
before 2.12.1-slfo.1.1_2.1 | 2.12.1-slfo.1.1_2.1 |
Show 38 moreShow less
| Package | Affected | Fixed |
|---|---|---|
python-PyJWTSUSE:Linux Enterprise Server 16.0 From an advisory covering 5 CVEs |
before 2.12.1-160000.2.1 | 2.12.1-160000.2.1 |
python-PyJWTSUSE:Linux Enterprise Server for SAP applications 16.0 From an advisory covering 5 CVEs |
before 2.12.1-160000.2.1 | 2.12.1-160000.2.1 |
python-PyJWTSUSE:Linux Micro 6.2 From an advisory covering 5 CVEs |
before 2.12.1-160000.2.1 | 2.12.1-160000.2.1 |
python-PyJWTSUSE:Linux Micro 6.0 From an advisory covering 5 CVEs |
before 2.9.0-3.1 | 2.9.0-3.1 |
python-PyJWTSUSE:Linux Enterprise Module for Public Cloud 15 SP4 From an advisory covering 5 CVEs |
before 2.8.0-150400.8.13.1 | 2.8.0-150400.8.13.1 |
python-PyJWTSUSE:Linux Enterprise Module for Python 3 15 SP7 From an advisory covering 5 CVEs |
before 2.8.0-150400.8.13.1 | 2.8.0-150400.8.13.1 |
python-PyJWTSUSE:Linux Enterprise High Performance Computing 15 SP4-ESPOS From an advisory covering 5 CVEs |
before 2.8.0-150400.8.13.1 | 2.8.0-150400.8.13.1 |
python-PyJWTSUSE:Linux Enterprise High Performance Computing 15 SP4-LTSS From an advisory covering 5 CVEs |
before 2.8.0-150400.8.13.1 | 2.8.0-150400.8.13.1 |
python-PyJWTSUSE:Linux Enterprise High Performance Computing 15 SP5-ESPOS From an advisory covering 5 CVEs |
before 2.8.0-150400.8.13.1 | 2.8.0-150400.8.13.1 |
python-PyJWTSUSE:Linux Enterprise High Performance Computing 15 SP5-LTSS From an advisory covering 5 CVEs |
before 2.8.0-150400.8.13.1 | 2.8.0-150400.8.13.1 |
python-PyJWTSUSE:Linux Enterprise Server 15 SP4-LTSS From an advisory covering 5 CVEs |
before 2.8.0-150400.8.13.1 | 2.8.0-150400.8.13.1 |
python-PyJWTSUSE:Linux Enterprise Server 15 SP5-LTSS From an advisory covering 5 CVEs |
before 2.8.0-150400.8.13.1 | 2.8.0-150400.8.13.1 |
python-PyJWTSUSE:Linux Enterprise Server 15 SP6-LTSS From an advisory covering 5 CVEs |
before 2.8.0-150400.8.13.1 | 2.8.0-150400.8.13.1 |
python-PyJWTSUSE:Linux Enterprise Server for SAP Applications 15 SP4 From an advisory covering 5 CVEs |
before 2.8.0-150400.8.13.1 | 2.8.0-150400.8.13.1 |
python-PyJWTSUSE:Linux Enterprise Server for SAP Applications 15 SP5 From an advisory covering 5 CVEs |
before 2.8.0-150400.8.13.1 | 2.8.0-150400.8.13.1 |
python-PyJWTSUSE:Linux Enterprise Server for SAP Applications 15 SP6 From an advisory covering 5 CVEs |
before 2.8.0-150400.8.13.1 | 2.8.0-150400.8.13.1 |
python-PyJWTSUSE:Linux Enterprise Micro 5.5 From an advisory covering 4 CVEs |
before 2.4.0-150200.3.14.1 | 2.4.0-150200.3.14.1 |
python-PyJWTSUSE:Linux Enterprise Module for Basesystem 15 SP7 From an advisory covering 4 CVEs |
before 2.4.0-150200.3.14.1 | 2.4.0-150200.3.14.1 |
python-PyJWTSUSE:Linux Enterprise High Performance Computing 15 SP4-ESPOS From an advisory covering 4 CVEs |
before 2.4.0-150200.3.14.1 | 2.4.0-150200.3.14.1 |
python-PyJWTSUSE:Linux Enterprise High Performance Computing 15 SP4-LTSS From an advisory covering 4 CVEs |
before 2.4.0-150200.3.14.1 | 2.4.0-150200.3.14.1 |
python-PyJWTSUSE:Linux Enterprise High Performance Computing 15 SP5-ESPOS From an advisory covering 4 CVEs |
before 2.4.0-150200.3.14.1 | 2.4.0-150200.3.14.1 |
python-PyJWTSUSE:Linux Enterprise High Performance Computing 15 SP5-LTSS From an advisory covering 4 CVEs |
before 2.4.0-150200.3.14.1 | 2.4.0-150200.3.14.1 |
python-PyJWTSUSE:Linux Enterprise Server 15 SP4-LTSS From an advisory covering 4 CVEs |
before 2.4.0-150200.3.14.1 | 2.4.0-150200.3.14.1 |
python-PyJWTSUSE:Linux Enterprise Server 15 SP5-LTSS From an advisory covering 4 CVEs |
before 2.4.0-150200.3.14.1 | 2.4.0-150200.3.14.1 |
python-PyJWTSUSE:Linux Enterprise Server 15 SP6-LTSS From an advisory covering 4 CVEs |
before 2.4.0-150200.3.14.1 | 2.4.0-150200.3.14.1 |
python-PyJWTSUSE:Linux Enterprise Server for SAP Applications 15 SP4 From an advisory covering 4 CVEs |
before 2.4.0-150200.3.14.1 | 2.4.0-150200.3.14.1 |
python-PyJWTSUSE:Linux Enterprise Server for SAP Applications 15 SP5 From an advisory covering 4 CVEs |
before 2.4.0-150200.3.14.1 | 2.4.0-150200.3.14.1 |
python-PyJWTSUSE:Linux Enterprise Server for SAP Applications 15 SP6 From an advisory covering 4 CVEs |
before 2.4.0-150200.3.14.1 | 2.4.0-150200.3.14.1 |
pyjwtUbuntu:25.10 |
All versions, plus listed versions 2.10.1-22.10.1-2ubuntu0.1 |
None known |
pyjwtUbuntu:26.04:LTS |
before 2.10.1-4ubuntu1.1, plus listed versions 2.10.1-22.10.1-32.10.1-3build12.10.1-42.10.1-4ubuntu1 |
2.10.1-4ubuntu1.1 |
pyjwtUbuntu:Pro:16.04:LTS From an advisory covering 5 CVEs |
before 1.3.0-1ubuntu0.1+esm2, plus listed versions 1.0.0-0ubuntu11.3.0-11.3.0-1ubuntu0.11.3.0-1ubuntu0.1+esm1 |
1.3.0-1ubuntu0.1+esm2 |
pyjwtUbuntu:Pro:18.04:LTS From an advisory covering 5 CVEs |
before 1.5.3+ds1-1ubuntu0.1+esm2, plus listed versions 1.4.2-1.11.5.3+ds1-11.5.3+ds1-1ubuntu0.11.5.3+ds1-1ubuntu0.1+esm1 |
1.5.3+ds1-1ubuntu0.1+esm2 |
pyjwtUbuntu:Pro:20.04:LTS From an advisory covering 5 CVEs |
before 1.7.1-2ubuntu2.1+esm2, plus listed versions 1.7.0-21.7.1-11.7.1-2ubuntu11.7.1-2ubuntu21.7.1-2ubuntu2.11.7.1-2ubuntu2.1+esm1 |
1.7.1-2ubuntu2.1+esm2 |
pyjwtUbuntu:22.04:LTS From an advisory covering 5 CVEs |
before 2.3.0-1ubuntu0.4, plus listed versions 1.7.1-2ubuntu22.1.0-12.3.0-12.3.0-1ubuntu0.12.3.0-1ubuntu0.22.3.0-1ubuntu0.3 |
2.3.0-1ubuntu0.4 |
pyjwtUbuntu:24.04:LTS From an advisory covering 5 CVEs |
before 2.7.0-1ubuntu0.2, plus listed versions 2.7.0-12.7.0-1ubuntu0.1 |
2.7.0-1ubuntu0.2 |
pyjwtUbuntu:26.04:LTS From an advisory covering 5 CVEs |
before 2.10.1-4ubuntu1.1, plus listed versions 2.10.1-22.10.1-32.10.1-3build12.10.1-42.10.1-4ubuntu1 |
2.10.1-4ubuntu1.1 |
python-PyJWTopenSUSE:Tumbleweed From an advisory covering 5 CVEs |
before 2.13.0-1.1 | 2.13.0-1.1 |
python-PyJWTopenSUSE:Leap 16.0 From an advisory covering 5 CVEs |
before 2.12.1-160000.2.1 | 2.12.1-160000.2.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected, facts | ||
| 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-48523 is a medium vulnerability (CVSS 5.4) in Jpadilla Pyjwt, published May 28, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.13%, the 2nd percentile. Fixed in pyjwt 2.13.0.
References
github.com/jpadilla/pyjwt/security/advisories/GHSA-jq35-7prp-9v3f
nvd.nist.gov/vuln/detail/CVE-2026-48523
github.com/pypa/advisory-database/tree/main/vulns/pyjwt/PYSEC-2026-176.yaml
github.com/advisories/GHSA-jq35-7prp-9v3f
docs.bell-sw.com/security/cves/CVE-2026-48523
github.com/CVEProject/cvelistV5/tree/main/cves/2026/48xxx/CVE-2026-48523.json
Show 26 moreShow less
security-tracker.debian.org/tracker/CVE-2026-48523
github.com/jpadilla/pyjwt
suse.com/support/update/announcement/2026/suse-su-202622138-1
bugzilla.suse.com/1266798
bugzilla.suse.com/1266799
bugzilla.suse.com/1266800
bugzilla.suse.com/1266801
bugzilla.suse.com/1266802
suse.com/security/cve/CVE-2026-48522
suse.com/security/cve/CVE-2026-48523
suse.com/security/cve/CVE-2026-48524
suse.com/security/cve/CVE-2026-48525
suse.com/security/cve/CVE-2026-48526
suse.com/support/update/announcement/2026/suse-su-202622170-1
suse.com/support/update/announcement/2026/suse-su-202622220-1
suse.com/support/update/announcement/2026/suse-su-202622238-1
suse.com/support/update/announcement/2026/suse-su-20262626-1
suse.com/support/update/announcement/2026/suse-su-20262627-1
ubuntu.com/security/CVE-2026-48523
cve.org/CVERecord?id=CVE-2026-48523
github.com/jpadilla/pyjwt/commit/95791b1759b8aa4f2203575d344d5c78564cdc81
ubuntu.com/security/notices/USN-8823-1
ubuntu.com/security/CVE-2026-48522
ubuntu.com/security/CVE-2026-48524
ubuntu.com/security/CVE-2026-48525
ubuntu.com/security/CVE-2026-48526
Left out here: the rest of 2 source descriptions. The JSON record has them.