{"id":"CVE-2026-48524","aliases":["AZL-93027","BELL-CVE-2026-48524","CLSA-2026-1783299703","CLSA-2026-1786944250","DEBIAN-CVE-2026-48524","EUVD-2026-32916","GHSA-fhv5-28vv-h8m8","PYSEC-2026-177","ROOT-APP-PYPI-CVE-2026-48524","SUSE-SU-2026:22138-1","SUSE-SU-2026:22170-1","SUSE-SU-2026:22220-1","SUSE-SU-2026:22238-1","SUSE-SU-2026:2626-1","UBUNTU-CVE-2026-48524","USN-8823-1","openSUSE-SU-2026:11024-1","openSUSE-SU-2026:21095-1"],"status":"published","title":"PyJWT: PyJWKClient unbounded JWKS endpoint requests via attacker-controlled kid values (DoS)","description":"PyJWT is a JSON Web Token implementation in Python. Prior to 2.13.0, 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. 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. This vulnerability is fixed in 2.13.0.","severity":{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"low","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-10","score":0.004,"percentile":0.34572,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-460","CWE-755"],"published":"2026-05-28T15:07:35Z","modified":"2026-10-28T10:15:03Z","fixes":[{"ecosystem":"PyPI","package":"pyjwt","fixed_in":["2.13.0"],"sources":["ghsa","osv"]},{"ecosystem":"Azure Linux:3","package":"python-jwt","fixed_in":["2.13.0-1"],"sources":["osv"]},{"ecosystem":"Alpaquita:25","package":"py3-jwt","fixed_in":["2.13.0-r0"],"sources":["osv"]},{"ecosystem":"Alpaquita:stream","package":"py3-jwt","fixed_in":["2.13.0-r0"],"sources":["osv"]},{"ecosystem":"Debian:14","package":"pyjwt","fixed_in":["2.13.0-1"],"sources":["osv"]},{"ecosystem":"Root:PyPI","package":"PyJWT","fixed_in":["2.9.0+aikido.6","2.8.0+aikido.5","2.5.0+aikido.5","2.12.1+aikido.3","2.4.0+aikido.6","2.10.1+aikido.7","2.12.0+aikido.4","2.4.0+aikido.7","2.12.0+aikido.5","2.8.0+aikido.6","2.12.1+aikido.4","2.5.0+aikido.6","2.12.1+aikido.5"],"sources":["osv"]},{"ecosystem":"Ubuntu:24.04:LTS","package":"pyjwt","fixed_in":["2.7.0-1ubuntu0.2"],"sources":["osv"]},{"ecosystem":"Ubuntu:26.04:LTS","package":"pyjwt","fixed_in":["2.10.1-4ubuntu1.1"],"sources":["osv"]}],"affected":[{"source":"ghsa","ecosystem":"PyPI","package":"pyjwt","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"2.0.0"},{"last_affected":"2.12.1"},{"fixed":"2.13.0"}]}]},{"source":"osv","ecosystem":"Azure Linux:3","package":"python-jwt","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.13.0-1"}]}]},{"source":"osv","ecosystem":"Alpaquita:25","package":"py3-jwt","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"2.10.1-r0"},{"fixed":"2.13.0-r0"}]}]},{"source":"osv","ecosystem":"Alpaquita:stream","package":"py3-jwt","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"2.8.0-r1"},{"fixed":"2.13.0-r0"}]}]},{"source":"osv","ecosystem":"TuxCare:PyPI","package":"pyjwt","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"2.10.1"},{"fixed":"2.10.1.post2+tuxcare"}]}],"versions":["2.10.1","2.10.1.post1+tuxcare"],"bundled":4},{"source":"osv","ecosystem":"TuxCare:PyPI","package":"pyjwt","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"2.8.0"},{"fixed":"2.8.0.post3+tuxcare"}]}],"versions":["2.8.0","2.8.0.post1+tuxcare","2.8.0.post2+tuxcare"],"bundled":2},{"source":"osv","ecosystem":"Debian:12","package":"pyjwt","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["2.10.1-1","2.10.1-2","2.10.1-3","2.10.1-4","2.11.0-2","2.12.1-1","2.13.0-1","2.14.0-1","2.15.0-1","2.15.1-1","2.6.0-1","2.6.0-1+deb12u1","2.7.0-1"]},{"source":"osv","ecosystem":"Debian:13","package":"pyjwt","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["2.10.1-2","2.10.1-2+deb13u1","2.10.1-3","2.10.1-4","2.11.0-2","2.12.1-1","2.13.0-1","2.14.0-1","2.15.0-1","2.15.1-1"]},{"source":"osv","ecosystem":"Debian:14","package":"pyjwt","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.13.0-1"}]}],"versions":["2.10.1-2","2.10.1-3","2.10.1-4","2.11.0-2","2.12.1-1"]},{"source":"osv","ecosystem":"PyPI","package":"pyjwt","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"2.0.0"},{"fixed":"2.13.0"}]}],"versions":["2.0.0","2.0.1","2.1.0","2.10.0","2.10.1","2.11.0","2.12.0","2.12.1","2.2.0","2.3.0","2.4.0","2.5.0","2.6.0","2.7.0","2.8.0","2.9.0"]},{"source":"osv","ecosystem":"PyPI","package":"pyjwt","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.13.0"}]}],"versions":["0.1.1","0.1.2","0.1.3","0.1.4","0.1.5","0.1.6","0.1.7","0.1.8","0.1.9","0.2.0","0.2.1","0.2.3","0.3.0","0.3.1","0.3.2","0.4.0","0.4.1","0.4.2","0.4.3","1.0.0","1.0.1","1.1.0","1.3.0","1.4.0","1.4.1","1.4.2","1.5.0","1.5.1","1.5.2","1.5.3","1.6.0","1.6.1","1.6.3","1.6.4","1.7.0","1.7.1","2.0.0","2.0.0a1","2.0.0a2","2.0.1","2.1.0","2.10.0","2.10.1","2.11.0","2.12.0","2.12.1","2.2.0","2.3.0","2.4.0","2.5.0","2.6.0","2.7.0","2.8.0","2.9.0"]},{"source":"osv","ecosystem":"Root:PyPI","package":"PyJWT","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.9.0+aikido.6"},{"fixed":"2.8.0+aikido.5"},{"fixed":"2.5.0+aikido.5"},{"fixed":"2.12.1+aikido.3"},{"fixed":"2.4.0+aikido.6"},{"fixed":"2.10.1+aikido.7"},{"fixed":"2.12.0+aikido.4"},{"fixed":"2.4.0+aikido.7"},{"fixed":"2.12.0+aikido.5"},{"fixed":"2.8.0+aikido.6"},{"fixed":"2.12.1+aikido.4"},{"fixed":"2.5.0+aikido.6"},{"fixed":"2.12.1+aikido.5"}]}]},{"source":"osv","ecosystem":"SUSE:Linux Micro 6.1","package":"python-PyJWT","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.12.1-slfo.1.1_2.1"}]}],"bundled":5},{"source":"osv","ecosystem":"SUSE:Linux Enterprise Server 16.0","package":"python-PyJWT","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.12.1-160000.2.1"}]}],"bundled":5},{"source":"osv","ecosystem":"SUSE:Linux Enterprise Server for SAP applications 16.0","package":"python-PyJWT","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.12.1-160000.2.1"}]}],"bundled":5},{"source":"osv","ecosystem":"SUSE:Linux Micro 6.2","package":"python-PyJWT","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.12.1-160000.2.1"}]}],"bundled":5},{"source":"osv","ecosystem":"SUSE:Linux Micro 6.0","package":"python-PyJWT","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.9.0-3.1"}]}],"bundled":5},{"source":"osv","ecosystem":"SUSE:Linux Enterprise Module for Public Cloud 15 SP4","package":"python-PyJWT","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.8.0-150400.8.13.1"}]}],"bundled":5},{"source":"osv","ecosystem":"SUSE:Linux Enterprise Module for Python 3 15 SP7","package":"python-PyJWT","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.8.0-150400.8.13.1"}]}],"bundled":5},{"source":"osv","ecosystem":"SUSE:Linux Enterprise High Performance Computing 15 SP4-ESPOS","package":"python-PyJWT","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.8.0-150400.8.13.1"}]}],"bundled":5},{"source":"osv","ecosystem":"SUSE:Linux Enterprise High Performance Computing 15 SP4-LTSS","package":"python-PyJWT","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.8.0-150400.8.13.1"}]}],"bundled":5},{"source":"osv","ecosystem":"SUSE:Linux Enterprise High Performance Computing 15 SP5-ESPOS","package":"python-PyJWT","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.8.0-150400.8.13.1"}]}],"bundled":5},{"source":"osv","ecosystem":"SUSE:Linux Enterprise High Performance Computing 15 SP5-LTSS","package":"python-PyJWT","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.8.0-150400.8.13.1"}]}],"bundled":5},{"source":"osv","ecosystem":"SUSE:Linux Enterprise Server 15 SP4-LTSS","package":"python-PyJWT","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.8.0-150400.8.13.1"}]}],"bundled":5},{"source":"osv","ecosystem":"SUSE:Linux Enterprise Server 15 SP5-LTSS","package":"python-PyJWT","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.8.0-150400.8.13.1"}]}],"bundled":5},{"source":"osv","ecosystem":"SUSE:Linux Enterprise Server 15 SP6-LTSS","package":"python-PyJWT","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.8.0-150400.8.13.1"}]}],"bundled":5},{"source":"osv","ecosystem":"SUSE:Linux Enterprise Server for SAP Applications 15 SP4","package":"python-PyJWT","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.8.0-150400.8.13.1"}]}],"bundled":5},{"source":"osv","ecosystem":"SUSE:Linux Enterprise Server for SAP Applications 15 SP5","package":"python-PyJWT","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.8.0-150400.8.13.1"}]}],"bundled":5},{"source":"osv","ecosystem":"SUSE:Linux Enterprise Server for SAP Applications 15 SP6","package":"python-PyJWT","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.8.0-150400.8.13.1"}]}],"bundled":5},{"source":"osv","ecosystem":"Ubuntu:24.04:LTS","package":"pyjwt","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.7.0-1ubuntu0.2"}]}],"versions":["2.7.0-1","2.7.0-1ubuntu0.1"]},{"source":"osv","ecosystem":"Ubuntu:25.10","package":"pyjwt","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["2.10.1-2","2.10.1-2ubuntu0.1"]},{"source":"osv","ecosystem":"Ubuntu:26.04:LTS","package":"pyjwt","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.10.1-4ubuntu1.1"}]}],"versions":["2.10.1-2","2.10.1-3","2.10.1-3build1","2.10.1-4","2.10.1-4ubuntu1"]},{"source":"osv","ecosystem":"Ubuntu:Pro:16.04:LTS","package":"pyjwt","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.3.0-1ubuntu0.1+esm2"}]}],"versions":["1.0.0-0ubuntu1","1.3.0-1","1.3.0-1ubuntu0.1","1.3.0-1ubuntu0.1+esm1"],"bundled":5},{"source":"osv","ecosystem":"Ubuntu:Pro:18.04:LTS","package":"pyjwt","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.5.3+ds1-1ubuntu0.1+esm2"}]}],"versions":["1.4.2-1.1","1.5.3+ds1-1","1.5.3+ds1-1ubuntu0.1","1.5.3+ds1-1ubuntu0.1+esm1"],"bundled":5},{"source":"osv","ecosystem":"Ubuntu:Pro:20.04:LTS","package":"pyjwt","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.7.1-2ubuntu2.1+esm2"}]}],"versions":["1.7.0-2","1.7.1-1","1.7.1-2ubuntu1","1.7.1-2ubuntu2","1.7.1-2ubuntu2.1","1.7.1-2ubuntu2.1+esm1"],"bundled":5},{"source":"osv","ecosystem":"Ubuntu:22.04:LTS","package":"pyjwt","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.3.0-1ubuntu0.4"}]}],"versions":["1.7.1-2ubuntu2","2.1.0-1","2.3.0-1","2.3.0-1ubuntu0.1","2.3.0-1ubuntu0.2","2.3.0-1ubuntu0.3"],"bundled":5},{"source":"osv","ecosystem":"Ubuntu:24.04:LTS","package":"pyjwt","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.7.0-1ubuntu0.2"}]}],"versions":["2.7.0-1","2.7.0-1ubuntu0.1"],"bundled":5},{"source":"osv","ecosystem":"Ubuntu:26.04:LTS","package":"pyjwt","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.10.1-4ubuntu1.1"}]}],"versions":["2.10.1-2","2.10.1-3","2.10.1-3build1","2.10.1-4","2.10.1-4ubuntu1"],"bundled":5},{"source":"osv","ecosystem":"openSUSE:Tumbleweed","package":"python-PyJWT","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.13.0-1.1"}]}],"bundled":5},{"source":"osv","ecosystem":"openSUSE:Leap 16.0","package":"python-PyJWT","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.12.1-160000.2.1"}]}],"bundled":5}],"products":[{"vendor":"jpadilla","product":"pyjwt"},{"vendor":"pyjwt_project","product":"pyjwt"}],"references":[{"url":"https://github.com/jpadilla/pyjwt/security/advisories/GHSA-fhv5-28vv-h8m8","tags":["x_refsource_CONFIRM","Mitigation","Vendor Advisory","advisory","web","report"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-48524","tags":["web","advisory"]},{"url":"https://github.com/pypa/advisory-database/tree/main/vulns/pyjwt/PYSEC-2026-177.yaml","tags":["web"]},{"url":"https://github.com/github/advisory-database/pull/8522","tags":["web"]},{"url":"https://github.com/advisories/GHSA-fhv5-28vv-h8m8"},{"url":"https://docs.bell-sw.com/security/cves/CVE-2026-48524","tags":["advisory"]},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/48xxx/CVE-2026-48524.json","tags":["advisory"]},{"url":"https://security-tracker.debian.org/tracker/CVE-2026-48524","tags":["advisory"]},{"url":"https://github.com/jpadilla/pyjwt","tags":["package"]},{"url":"https://www.suse.com/support/update/announcement/2026/suse-su-202622138-1/","tags":["advisory"]},{"url":"https://bugzilla.suse.com/1266798","tags":["report"]},{"url":"https://bugzilla.suse.com/1266799","tags":["report"]},{"url":"https://bugzilla.suse.com/1266800","tags":["report"]},{"url":"https://bugzilla.suse.com/1266801","tags":["report"]},{"url":"https://bugzilla.suse.com/1266802","tags":["report"]},{"url":"https://www.suse.com/security/cve/CVE-2026-48522","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-48523","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-48524","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-48525","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-48526","tags":["web"]},{"url":"https://www.suse.com/support/update/announcement/2026/suse-su-202622170-1/","tags":["advisory"]},{"url":"https://www.suse.com/support/update/announcement/2026/suse-su-202622220-1/","tags":["advisory"]},{"url":"https://www.suse.com/support/update/announcement/2026/suse-su-202622238-1/","tags":["advisory"]},{"url":"https://www.suse.com/support/update/announcement/2026/suse-su-20262626-1/","tags":["advisory"]},{"url":"https://ubuntu.com/security/CVE-2026-48524","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-48524","tags":["report"]},{"url":"https://ubuntu.com/security/notices/USN-8823-1","tags":["advisory"]},{"url":"https://ubuntu.com/security/CVE-2026-48522","tags":["report"]},{"url":"https://ubuntu.com/security/CVE-2026-48523","tags":["report"]},{"url":"https://ubuntu.com/security/CVE-2026-48525","tags":["report"]},{"url":"https://ubuntu.com/security/CVE-2026-48526","tags":["report"]},{"url":"","tags":["advisory"]}],"sources":{"cve":[{"id":"CVE-2026-48524","title":"PyJWT: PyJWKClient unbounded JWKS endpoint requests via attacker-controlled kid values (DoS)","description":"PyJWT is a JSON Web Token implementation in Python. Prior to 2.13.0, 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. 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. This vulnerability is fixed in 2.13.0.","status":"published","published":"2026-05-28T15:07:35.162Z","modified":"2026-05-28T19:17:11.798Z","cvss":[{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"low","assessor":"cna"}],"cwes":["CWE-460","CWE-755"],"updated_at":"2026-11-02T13:50:49.872037Z"}],"euvd":[{"id":"EUVD-2026-32916","description":"PyJWT is a JSON Web Token implementation in Python. Prior to 2.13.0, 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. 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. This vulnerability is fixed in 2.13.0.","status":"published","published":"2026-05-28T15:07:35Z","modified":"2026-05-28T19:17:11Z","cvss":[{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"low"}],"updated_at":"2026-11-02T18:21:01.680356Z"}],"ghsa":[{"id":"GHSA-fhv5-28vv-h8m8","title":"PyJWKClient unbounded JWKS endpoint requests via attacker-controlled kid values (DoS)","description":"\u003e [!NOTE]\n\u003e  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.\n\n## Summary\nPyJWKClient.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.\n\nAdditionally, fetch_data() finally block clears the JWKS cache on network error.\n\n## Root Cause\njwt/jwks_client.py:172-198 - get_signing_key(kid) calls get_signing_keys(refresh=True) for unknown kids, bypassing TTL cache with no cooldown.\njwt/jwks_client.py:120-122 - finally block writes None to cache on error, clearing valid data.\n\n## Impact\n- DoS against JWKS endpoint (unlimited requests per invalid token)\n- DoS against application (network I/O latency)\n- Cascading failure (rate limiting clears cache, breaking legitimate auth)\n\n## Suggested Fix\n1. Add refresh cooldown (refuse refresh more than once per TTL period)\n2. Move cache write from finally to else block\n\n## Affected Versions\nAll versions with PyJWKClient (2.4.0 through 2.12.1)","status":"published","published":"2026-06-15T17:28:46Z","modified":"2026-07-31T22:13:03Z","cvss":[{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"low"}],"cwes":["CWE-460","CWE-755"],"updated_at":"2026-11-02T14:40:55.903445Z"}],"nvd":[{"id":"CVE-2026-48524","description":"PyJWT is a JSON Web Token implementation in Python. Prior to 2.13.0, 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. 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. This vulnerability is fixed in 2.13.0.","status":"published","published":"2026-05-28T16:16:29.403Z","modified":"2026-10-26T13:10:00.14Z","cvss":[{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"low","assessor":"secondary"}],"cwes":["CWE-460","CWE-755"],"updated_at":"2026-11-02T14:12:21.244426Z"}],"osv":[{"id":"BELL-CVE-2026-48524","status":"published","published":"2026-06-02T06:11:45.911259Z","modified":"2026-06-23T07:15:07.611999361Z","cvss":[{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"low"}],"updated_at":"2026-11-02T15:28:24.391068Z"},{"id":"CVE-2026-48524","title":"PyJWT: PyJWKClient unbounded JWKS endpoint requests via attacker-controlled kid values (DoS)","description":"PyJWT is a JSON Web Token implementation in Python. Prior to 2.13.0, 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. 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. This vulnerability is fixed in 2.13.0.","status":"published","published":"2026-05-28T15:07:35.162Z","modified":"2026-10-28T02:30:46.203286069Z","cvss":[{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"low"}],"cwes":["CWE-460","CWE-755"],"updated_at":"2026-11-02T15:45:06.701612Z"},{"id":"DEBIAN-CVE-2026-48524","description":"PyJWT is a JSON Web Token implementation in Python. Prior to 2.13.0, 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. 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. This vulnerability is fixed in 2.13.0.","status":"published","published":"2026-05-28T16:16:29.403Z","modified":"2026-10-27T09:47:37.526376854Z","cvss":[{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"low"}],"updated_at":"2026-11-02T15:45:56.444225Z"},{"id":"GHSA-fhv5-28vv-h8m8","title":"PyJWKClient unbounded JWKS endpoint requests via attacker-controlled kid values (DoS)","description":"\u003e [!NOTE]\n\u003e  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.\n\n## Summary\nPyJWKClient.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.\n\nAdditionally, fetch_data() finally block clears the JWKS cache on network error.\n\n## Root Cause\njwt/jwks_client.py:172-198 - get_signing_key(kid) calls get_signing_keys(refresh=True) for unknown kids, bypassing TTL cache with no cooldown.\njwt/jwks_client.py:120-122 - finally block writes None to cache on error, clearing valid data.\n\n## Impact\n- DoS against JWKS endpoint (unlimited requests per invalid token)\n- DoS against application (network I/O latency)\n- Cascading failure (rate limiting clears cache, breaking legitimate auth)\n\n## Suggested Fix\n1. Add refresh cooldown (refuse refresh more than once per TTL period)\n2. Move cache write from finally to else block\n\n## Affected Versions\nAll versions with PyJWKClient (2.4.0 through 2.12.1)","status":"published","published":"2026-06-15T17:28:46Z","modified":"2026-09-10T03:50:49.375741307Z","cvss":[{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"low"}],"cwes":["CWE-460","CWE-755"],"updated_at":"2026-11-02T15:46:46.39441Z"},{"id":"PYSEC-2026-177","description":"PyJWT is a JSON Web Token implementation in Python. Prior to 2.13.0, 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. 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. This vulnerability is fixed in 2.13.0.","status":"published","published":"2026-05-28T16:16:29.403Z","modified":"2026-06-02T12:15:10.363704191Z","cvss":[{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"low"}],"updated_at":"2026-11-02T15:52:55.06457Z"},{"id":"UBUNTU-CVE-2026-48524","description":"PyJWT is a JSON Web Token implementation in Python. Prior to 2.13.0, 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. 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. This vulnerability is fixed in 2.13.0.","status":"published","published":"2026-05-28T16:16:00Z","modified":"2026-09-28T11:30:25.83202706Z","cvss":[{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"low"}],"updated_at":"2026-11-02T16:56:33.391918Z"},{"id":"AZL-93027","title":"CVE-2026-48524 affecting package python-jwt for versions less than 2.13.0-1","description":"PyJWT is a JSON Web Token implementation in Python. Prior to 2.13.0, 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. 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. This vulnerability is fixed in 2.13.0.","status":"published","published":"2026-05-28T16:16:29Z","modified":"2026-08-28T17:56:37.283012Z","updated_at":"2026-11-02T15:28:11.723718Z"},{"id":"CLSA-2026-1783299703","title":"TuxCare security update for pyjwt (4 CVEs)","description":"TuxCare rebuilt pyjwt to address 4 CVEs. Fixed in 2.10.1.post2+tuxcare.","status":"published","published":"2026-08-04T14:52:42Z","modified":"2026-10-15T09:48:05.500671074Z","updated_at":"2026-11-02T15:43:45.794021Z"},{"id":"CLSA-2026-1786944250","title":"TuxCare security update for pyjwt (2 CVEs)","description":"TuxCare rebuilt pyjwt to address 2 CVEs. Fixed in 2.8.0.post3+tuxcare.","status":"published","published":"2026-08-17T05:24:10Z","modified":"2026-10-15T09:48:05.58636375Z","updated_at":"2026-11-02T15:43:47.20725Z"},{"id":"openSUSE-SU-2026:11024-1","title":"python311-PyJWT-2.13.0-1.1 on GA media","description":"These are all security issues fixed in the python311-PyJWT-2.13.0-1.1 package on the GA media of openSUSE Tumbleweed.","status":"published","published":"2026-06-13T00:00:00Z","modified":"2026-06-14T14:00:06.198800158Z","updated_at":"2026-11-02T16:58:38.95195Z"},{"id":"openSUSE-SU-2026:21095-1","title":"Security update for python-PyJWT","description":"This update for python-PyJWT fixes the following issues\n\n- CVE-2026-48522: `PyJWKClient` passes URI arguments directly to `urllib.request.urlopen()` and allows for SSRF and\n  token forgery (bsc#1266798).\n- CVE-2026-48523: verifier-side algorithm allow-list bypass when `jwt.decode()` or `jwt.decode_complete()` are called\n  with a PyJWK key (bsc#1266799).\n- CVE-2026-48524: unlimited processing of JWTs with unknown kid values by `PyJWKClient.get_signing_key()` leads to\n  unbounded JWKS endpoint requests and DoS (bsc#1266800).\n- CVE-2026-48525: unbounded Base64URL decoding of unused payload segment in `b64=false` detached JWS allows for DoS\n  (bsc#1266801).\n- CVE-2026-48526: no validation of use of JSON Web Keys in HMAC algorithm when decoding JSON Web Tokens allows for\n  forged HS256 tokens (bsc#1266802).\n","status":"published","published":"2026-06-19T05:43:05Z","modified":"2026-06-30T18:24:40.576597716Z","updated_at":"2026-11-02T16:58:41.885092Z"},{"id":"ROOT-APP-PYPI-CVE-2026-48524","title":"CVE-2026-48524 in PyJWT - Patched by Root","description":"Root has patched CVE-2026-48524 in the PyJWT package for Root:PyPI. Multiple fixed versions available.","status":"published","published":"2026-10-28T09:09:40Z","modified":"2026-10-28T10:15:03.742363012Z","updated_at":"2026-11-02T15:53:28.259095Z"},{"id":"SUSE-SU-2026:22138-1","title":"Security update for python-PyJWT","description":"This update for python-PyJWT fixes the following issues\n\n- CVE-2026-48522: `PyJWKClient` passes URI arguments directly to `urllib.request.urlopen()` and allows for SSRF and\n  token forgery (bsc#1266798).\n- CVE-2026-48523: verifier-side algorithm allow-list bypass when `jwt.decode()` or `jwt.decode_complete()` are called\n  with a PyJWK key (bsc#1266799).\n- CVE-2026-48524: unlimited processing of JWTs with unknown kid values by `PyJWKClient.get_signing_key()` leads to\n  unbounded JWKS endpoint requests and DoS (bsc#1266800).\n- CVE-2026-48525: unbounded Base64URL decoding of unused payload segment in `b64=false` detached JWS allows for DoS\n  (bsc#1266801).\n- CVE-2026-48526: no validation of use of JSON Web Keys in HMAC algorithm when decoding JSON Web Tokens allows for\n  forged HS256 tokens (bsc#1266802).\n","status":"published","published":"2026-06-16T09:09:33Z","modified":"2026-06-18T18:24:17.888913553Z","updated_at":"2026-11-02T15:54:02.654057Z"},{"id":"SUSE-SU-2026:22170-1","title":"Security update for python-PyJWT","description":"This update for python-PyJWT fixes the following issues\n\n- CVE-2026-48522: `PyJWKClient` passes URI arguments directly to `urllib.request.urlopen()` and allows for SSRF and\n  token forgery (bsc#1266798).\n- CVE-2026-48523: verifier-side algorithm allow-list bypass when `jwt.decode()` or `jwt.decode_complete()` are called\n  with a PyJWK key (bsc#1266799).\n- CVE-2026-48524: unlimited processing of JWTs with unknown kid values by `PyJWKClient.get_signing_key()` leads to\n  unbounded JWKS endpoint requests and DoS (bsc#1266800).\n- CVE-2026-48525: unbounded Base64URL decoding of unused payload segment in `b64=false` detached JWS allows for DoS\n  (bsc#1266801).\n- CVE-2026-48526: no validation of use of JSON Web Keys in HMAC algorithm when decoding JSON Web Tokens allows for\n  forged HS256 tokens (bsc#1266802).\n","status":"published","published":"2026-06-19T05:44:26Z","modified":"2026-06-24T18:24:17.973821173Z","updated_at":"2026-11-02T15:54:02.654057Z"},{"id":"SUSE-SU-2026:22220-1","title":"Security update for python-PyJWT","description":"This update for python-PyJWT fixes the following issues\n\n- CVE-2026-48522: `PyJWKClient` passes URI arguments directly to `urllib.request.urlopen()` and allows for SSRF and\n  token forgery (bsc#1266798).\n- CVE-2026-48523: verifier-side algorithm allow-list bypass when `jwt.decode()` or `jwt.decode_complete()` are called\n  with a PyJWK key (bsc#1266799).\n- CVE-2026-48524: unlimited processing of JWTs with unknown kid values by `PyJWKClient.get_signing_key()` leads to\n  unbounded JWKS endpoint requests and DoS (bsc#1266800).\n- CVE-2026-48525: unbounded Base64URL decoding of unused payload segment in `b64=false` detached JWS allows for DoS\n  (bsc#1266801).\n- CVE-2026-48526: no validation of use of JSON Web Keys in HMAC algorithm when decoding JSON Web Tokens allows for\n  forged HS256 tokens (bsc#1266802).\n","status":"published","published":"2026-06-19T05:44:26Z","modified":"2026-06-24T18:24:19.894935573Z","updated_at":"2026-11-02T15:54:02.654057Z"},{"id":"SUSE-SU-2026:22238-1","title":"Security update for python-PyJWT","description":"This update for python-PyJWT fixes the following issues\n\n- CVE-2026-48522: `PyJWKClient` passes URI arguments directly to `urllib.request.urlopen()` and allows for SSRF and\n  token forgery (bsc#1266798).\n- CVE-2026-48523: verifier-side algorithm allow-list bypass when `jwt.decode()` or `jwt.decode_complete()` are called\n  with a PyJWK key (bsc#1266799).\n- CVE-2026-48524: unlimited processing of JWTs with unknown kid values by `PyJWKClient.get_signing_key()` leads to\n  unbounded JWKS endpoint requests and DoS (bsc#1266800).\n- CVE-2026-48525: unbounded Base64URL decoding of unused payload segment in `b64=false` detached JWS allows for DoS\n  (bsc#1266801).\n- CVE-2026-48526: no validation of use of JSON Web Keys in HMAC algorithm when decoding JSON Web Tokens allows for\n  forged HS256 tokens (bsc#1266802).\n","status":"published","published":"2026-06-16T08:55:32Z","modified":"2026-06-26T18:24:08.739071893Z","updated_at":"2026-11-02T15:54:02.654057Z"},{"id":"SUSE-SU-2026:2626-1","title":"Security update for python-PyJWT","description":"This update for python-PyJWT fixes the following issues\n\n- CVE-2026-48522: `PyJWKClient` passes URI arguments directly to `urllib.request.urlopen()` and allows for SSRF and\n  token forgery (bsc#1266798).\n- CVE-2026-48523: verifier-side algorithm allow-list bypass when `jwt.decode()` or `jwt.decode_complete()` are called\n  with a PyJWK key (bsc#1266799).\n- CVE-2026-48524: unlimited processing of JWTs with unknown kid values by `PyJWKClient.get_signing_key()` leads to\n  unbounded JWKS endpoint requests and DoS (bsc#1266800).\n- CVE-2026-48525: unbounded Base64URL decoding of unused payload segment in `b64=false` detached JWS allows for DoS\n  (bsc#1266801).\n- CVE-2026-48526: no validation of use of JSON Web Keys in HMAC algorithm when decoding JSON Web Tokens allows for\n  forged HS256 tokens (bsc#1266802).\n","status":"published","published":"2026-06-25T08:11:34Z","modified":"2026-06-26T08:15:09.085476812Z","updated_at":"2026-11-02T15:54:04.519245Z"},{"id":"USN-8823-1","title":"pyjwt vulnerabilities","description":"It was discovered that PyJWT incorrectly handled certain URIs when using\nPyJWKClient. A remote attacker could possibly use this issue to perform\nserver-side request forgery (SSRF) or expose sensitive local files.\nThis issue only affected Ubuntu 22.04 LTS, Ubuntu 24.04 LTS and Ubuntu\n26.04 LTS. (CVE-2026-48522)\n\nIt was discovered that PyJWT incorrectly verified cryptographic signatures\nwhen decoding tokens with PyJWK keys. A remote attacker could possibly\nuse this issue to bypass signature verification and forge valid JSON Web\nTokens. This issue only affected Ubuntu 26.04 LTS. (CVE-2026-48523)\n\nIt was discovered that PyJWT incorrectly handled unknown key identifiers\nin PyJWKClient. A remote attacker could possibly use this issue to cause\nPyJWT to make excessive network requests, resulting in a denial of service.\nThis issue only affected Ubuntu 24.04 LTS and Ubuntu 26.04 LTS.\n(CVE-2026-48524)\n\nIt was discovered that PyJWT incorrectly handled payload decoding during\ndetached JWS token verification. A remote attacker could possibly use\nthis issue to cause PyJWT to consume excessive resources, resulting in\na denial of service. This issue only affected Ubuntu 24.04 LTS and\nUbuntu 26.04 LTS. (CVE-2026-48525)\n\nIt was discovered that PyJWT incorrectly validated JSON Web Keys when\ndecoding tokens with both HMAC and asymmetric algorithms enabled. A remote\nattacker could possibly use this issue to forge valid tokens, resulting\nin an authentication bypass. (CVE-2026-48526)","status":"published","published":"2026-09-25T07:49:33Z","modified":"2026-09-28T11:42:45.323412495Z","updated_at":"2026-11-02T16:58:26.907654Z"}]}}
