GHSA-fhv5-28vv-h8m8 CVE-2026-48524 PYSEC-2026-177
PyJWKClient unbounded JWKS endpoint requests via attacker-controlled kid values (DoS)
- Severity
- 3.7 / 10
- Low · CVSS 3.1
- Exploit chance (EPSS)
- 0.40%
- Chance of exploitation in the next 30 days. Higher than 34.26% of scored vulnerabilities.
- Known exploited
- No
- Not in CISA's catalog
- Weakness
- CWE-460 Improper Cleanup on Thrown Exception
- CWE-755 Improper Handling of Exceptional Conditions
- Fix
2.13.0- Upgrade pyjwt to this version or later
Description
[!NOTE] The vulnerability surfaces only when a JWKS fetch fails; an attacker can attempt to provoke that with sustained unknown-kid traffic, but the outcome depends on upstream JWKS-endpoint behavior (rate limiting, transient errors) which is beyond the attacker's control. Impact is reduced auth availability until the next successful fetch, not complete denial of service.
Summary
PyJWKClient.get_signing_key() forces a fresh HTTP request to the JWKS endpoint for every JWT with an unknown kid value, with no rate limiting. Since kid comes from the unverified token header, an attacker can trigger unlimited outbound requests.
Additionally, fetch_data() finally block clears the JWKS cache on network error.
Root Cause
jwt/jwks_client.py:172-198 - get_signing_key(kid) calls get_signing_keys(refresh=True) for unknown kids, bypassing TTL cache with no cooldown. jwt/jwks_client.py:120-122 - finally block writes None to cache on error, clearing valid data.
Impact
- DoS against JWKS endpoint (unlimited requests per invalid token)
- DoS against application (network I/O latency)
- Cascading failure (rate limiting clears cache, breaking legitimate auth)
Suggested Fix
- Add refresh cooldown (refuse refresh more than once per TTL period)
- Move cache write from finally to else block
Affected Versions
All versions with PyJWKClient (2.4.0 through 2.12.1)
Affected versions
PyPI
How to fix
Move to the fixed version or later with your package manager, update the lockfile, and run your tests. If the package only arrives through another dependency, upgrade that dependency first. If none of its releases pulls a fixed version yet, force the version with your package manager's override.
pyjwt PyPI → 2.13.0
- pip
pip install --upgrade "pyjwt>=2.13.0"- poetry
poetry add "pyjwt>=2.13.0"- uv
uv add "pyjwt>=2.13.0"
Severity breakdown
CVSS 3.1 3.7
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L
- Attack vector
- Network
- Attack complexity
- High
- Privileges required
- None
- User interaction
- None
- Scope
- Unchanged
- Confidentiality
- None
- Integrity
- None
- Availability
- Low
Weakness
CWE-460: Improper Cleanup on Thrown Exception
The product does not clean up its state or incorrectly cleans up its state when an exception is thrown, leading to unexpected state or control flow.
How to prevent it
- Implementation: If one breaks from a loop or function by throwing an exception, make sure that cleanup happens or that you should exit the program. Use throwing exceptions sparsely.
CWE-755: Improper Handling of Exceptional Conditions
The product does not handle or incorrectly handles an exceptional condition.
References
Advisories
Packages
Other links
Timeline
- Published
- Last updated by the source
- Latest EPSS score
Related advisories
| Advisory | Severity | Why it's related |
|---|---|---|
| GHSA-pxh4-856f-4h89 PyJWT: HS256/384/512 verify accepts empty HMAC key via oct JWK (PyJWK/PyJWKClient) enabling token forgery | High | Also affects pyjwt |
| GHSA-gvp8-978c-rx2q PyJWT.decode() reintroduces options-dict mutation, enabling silent claim-verification bypass on dict reuse | Medium | Also affects pyjwt |
| GHSA-x33g-cr3x-6449 PyJWT accepts inconsistent OKP x/d JWKs, causing public/private key identity confusion | High | Also affects pyjwt |
| GHSA-w6j9-cwv2-h6wq PyJWT: Malformed RSA JWK aborts parsing of an entire JWK Set | High | Also affects pyjwt |
| GHSA-w2cx-738m-mc7w PyJWT accepts public JWK containers as HMAC secrets | High | Also affects pyjwt |
| GHSA-r6x4-923q-g947 PyJWT BOM Bypass | High | Also affects pyjwt |
| GHSA-p4g4-x82p-q773 PyJWT: Public keys in DER form are accepted as HMAC secrets, bypassing the CVE-2022-29217 guard | High | Also affects pyjwt |
| GHSA-jwrc-g2q2-pq5p PyJWT: ReDoS vulnerability when calling the `is_pem_format` function. | Medium | Also affects pyjwt |
MergeHarbor checks every repository's dependencies against this database, ranks what matters by exploitability and reachability, routes it to the owning team and opens the fix pull request.
Check your repos with MergeHarbor