Skip to content

← Public intelligence

PyPI package

pyjwt

Open actionable advisories and recorded vendor fixes. This public package view has no inventory attached and cannot establish whether your deployment is affected. A vendor fix never resolves your finding; verify your installed version and the source guidance.

Open advisories

23 actionable advisories, newest first. Withdrawn advisories and news are excluded. Coverage is partial.

  1. High, CVSS 7.4PyPIAmendedPublished

    PyJWT: HS256/384/512 verify accepts empty HMAC key via oct JWK (PyJWK/PyJWKClient) enabling token forgery

    GHSA-pxh4-856f-4h89

    Affected
    • PyPI pyjwt <= 2.13.0
    Fixed in
    2.14.0· Vendor fix available
    Issue
    HMACAlgorithm.fromjwk accepts a symmetric (kty=oct) JWK whose k value is the empty string and returns a zero-length key without raising. When a token is then verified with that key object (a PyJWK, or a PyJWK resolved by PyJWKSet / PyJWKClient), the HMAC verifier computes HMAC(key=b"", signinginput) and accepts any token an attacker forged with the same empty key. The attacker needs no secret knowledge: they reproduce the digest locally with an empty key and set the token's kid to the empty-k JWK. The empty-key rejection that HMACAlgorithm.preparekey performs for string/bytes secrets (added in 2.13.0) was never propagated to the sibling fromjwk code path, so the JWK/JWKS verification route stays exploitable. Under default decode options this path only emits an InsecureKeyLengthWarning, not an error, so verification still succeeds. This is the same "empty/nil HMAC key is accepted by verify" defect the JWT ecosystem is currently closing library-side: fast-jwt CVE-2026-44351…

    Recommended action: Upgrade to 2.14.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.com (1)osv.dev (2)Source checked Evidence →
  2. Medium, CVSS 6.5PyPIAmendedPublished

    PyJWT accepts inconsistent OKP x/d JWKs, causing public/private key identity confusion

    CVE-2026-102275 · GHSA-x33g-cr3x-6449

    Affected
    • PyPI pyjwt >= 2.1.0, <= 2.14.0
    Fixed in
    2.15.0· Vendor fix available
    Issue
    PyJWT accepts internally inconsistent OKP private JWKs where the declared public key x does not correspond to the supplied private key d. When d is present, OKPAlgorithm.fromjwk() constructs the Ed25519/Ed448 private key from d without verifying that the public key derived from d matches x. As a result, the original JWK can contain one public key identity while PyJWT performs cryptographic operations using a different key. In affected DPoP integrations, this can allow a stolen sender-constrained access token to be used without possession of the legitimate holder's private key. Details The vulnerable logic is in jwt/algorithms.py: When d is present, x is parsed but never compared with the public key derived from d. For example, PyJWT accepts: even though x and d belong to different key pairs. The behavior has existed since OKP private-JWK import was introduced: Ed25519: PyJWT 2.1.0+ Ed448: PyJWT 2.2.0+ Confirmed through PyJWT 2.14.0 and current master A correct import should…

    Recommended action: Upgrade to 2.15.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.com (1)osv.dev (2)Source checked Evidence →
  3. Medium, CVSS 5.3PyPIAmendedPublished

    PyJWT: Unauthenticated RecursionError DoS in pre-verification payload parse (PyJWKClient.get_signing_key_from_jwt / verify_signature=False)

    CVE-2026-101918 · GHSA-42vr-xj54-vc7v

    Affected
    • PyPI pyjwt >= 2.0.0a1, <= 2.14.0
    Fixed in
    2.15.0· Vendor fix available
    Issue
    PyJWKClient.getsigningkeyfromjwt(token) — the first step of the JWKS verification flow documented in docs/usage.rst — must decode a token's payload before its signature can be checked, via jwt.apijwt.decodecomplete(token, options={"verifysignature": False}). That call parses the payload with json.loads in PyJWT.decodepayload (jwt/apijwt.py:297-300), whose except clause catches only ValueError. A payload that is valid JSON but nested ~20,000 levels deep makes json.loads raise RecursionError, which is not a ValueError and escapes as a raw, undocumented exception type — not DecodeError, InvalidTokenError, or PyJWTError, so every documented error-handling pattern in docs/usage.rst misses it. The token needs no valid signature and no network access — the crash happens during payload parsing, before the kid is even looked up. A single unauthenticated ~50KB request crashes the caller's auth handler (HTTP 500 / dead worker), repeatably. The same path is reachable through plain…

    Recommended action: Upgrade to 2.15.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.com (1)osv.dev (2)Source checked Evidence →
  4. Medium, CVSS 4.4PyPIAmendedPublished

    PyJWT: ReDoS vulnerability when calling the is_pem_format function.

    CVE-2026-102270 · GHSA-jwrc-g2q2-pq5p

    Affected
    • PyPI pyjwt <= 2.13.0
    Fixed in
    2.14.0· Vendor fix available
    Issue
    There is a Re-DoS vulnerability in the ispemformat function which results in a intesive CPU usage if an attacker is been able to provide a custom certificate. Details The problem is that the lazy quantifier .+? will always first try to match as little as possible until it finds a ---- END. Normally this means the complexity of this should be O(N). However, by providing an input which consists only of ----BEGIN CERTIFICATE----- lines and no ---- END line, the regex algorithm will first try to match the first line and then, with the lazy quantifier, all the lines until the end O(N), which then fails since it is unable to find a ---- END line. It will then jump to the next line, resulting in N re-scans of the whole string, which means the complexity basically results in O(N²). PoC Impact The attacker could use extensive resources, which could make the resource (e.g. a web server) unavailable. Maintainer update (2026-09-10): We reproduced the reported quadratic regex behavior on…

    Recommended action: Upgrade to 2.14.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.com (1)osv.dev (2)Source checked Evidence →
  5. High, CVSS 7.4PyPIAmendedPublished

    PyJWT: PyJWK accepts empty HMAC keys, bypassing PyJWT's empty-key validation

    CVE-2026-102266 · GHSA-9j54-fg26-wv3r

    Affected
    • PyPI pyjwt >= 2.13.0, < 2.14.0
    Fixed in
    2.14.0· Vendor fix available
    Issue
    A service that verifies HS256 tokens using an empty oct JWK through PyJWK, including a PyJWK obtained from PyJWKSet, can therefore accept attacker-generated tokens as authenticated. PyJWT 2.13.0 rejects an empty HMAC key when it is supplied through the raw str/bytes key path, but accepts the same zero-length key when it is supplied as a symmetric PyJWK. An oct JWK containing an empty Base64URL key value: is decoded to b"". During signature verification, the PyJWK path uses this decoded value directly and does not invoke the empty-key validation in HMACAlgorithm.preparekey. With the default enforceminimumkeylength=False, PyJWT emits a warning and proceeds with HMAC verification using the zero-length key. An attacker can independently calculate HMAC-SHA256(b"", signinginput) and create valid HS256 JWTs with arbitrary claims. A service that verifies HS256 tokens using an empty oct JWK through PyJWK or PyJWKSet can therefore accept attacker-generated tokens as authenticated. The…

    Recommended action: Upgrade to 2.14.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.com (1)osv.dev (2)Source checked Evidence →
  6. Medium, CVSS 5.3PyPIAmendedPublished

    PyJWT: Uncaught RecursionError in jwt.decode() on deeply nested token header

    CVE-2026-102265 · GHSA-8wjv-2p76-3863

    Affected
    • PyPI pyjwt >= 2.13.0, < 2.14.0
    Fixed in
    2.14.0· Vendor fix available
    Issue
    Package pyjwt (PyPI) Affected versions tested & verified on: 2.13.0. Every version whose PyJWS.load() translates only ValueError is affected Description PyJWS.looad() (jwt/apijws.py:337) splits the compact token, base64url decodes the header segment and hands it to json.loads() before verifysignature() runs. The parse is wrapped in except ValueError as e: raise DecodeError(...). That is what makes the documented contract sufficient for untrusted input: except jwt.PyJWTError (or InvalidTokenError) around jwt.decode(token, key, algorithms=[...]). CPython's JSON decoder raises RecursionError (a RuntimeError subclass, not a ValueError) once nesting crosses the native stack guard. That exception leaves load(), then jwt.decode(), and matches no PyJWTError handlerr at all. No key and no valid signature are needed: the header is parsed first, so a single unauthenticated request with an unsigned token suffices. Scope: the recursion threshold is ~65,000 nesting levels; below it the same input…

    Recommended action: Upgrade to 2.14.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.com (1)osv.dev (2)Source checked Evidence →
  7. Medium, CVSS 4.8PyPIAmendedPublished

    PyJWT: Non-canonical signature segments enable raw-token revocation bypass

    CVE-2026-102269 · GHSA-hxm8-2xgr-2p9m

    Affected
    • PyPI pyjwt <= 2.13.0
    Fixed in
    2.14.0· Vendor fix available
    Issue
    PyJWT 2.13.0 accepts compact JWS signature segments containing characters that are not in the Base64URL alphabet. Appending !!!! to a valid signature does not change the decoded signature bytes or authenticated claims, but it changes the serialized token and its SHA-256 hash. An application that indexes logout or revocation state by the raw token therefore rejects the logged-out token and accepts its no-key alternate serialization. This report separates two issues: permissive compact-JWS decoding is the library behavior, while using raw serialized JWT text as a security identity is a dangerous application composition. A jti-indexed control blocks both representations. Affected Version Confirmed with PyJWT 2.13.0 on CPython 3.13. The mutation changes only the signature segment and requires no signing key. End-to-End Reproduction The loopback-only lab performs: 1. Issue a valid HS256 admin token. 2. Access /protected successfully. 3. Log out the canonical token and store…

    Recommended action: Upgrade to 2.14.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.com (1)osv.dev (2)Source checked Evidence →
  8. Critical, CVSS 9.1PyPIAmendedPublished

    PyJWT: Asymmetric-PEM detection bypass: whitespace/line-ending-mutated public keys skip the HS/asymmetric confusion guard

    CVE-2026-102268 · GHSA-ffc3-869f-jxw9

    Affected
    • PyPI pyjwt <= 2.13.0
    Fixed in
    2.14.0· Vendor fix available
    Issue
    Prerequisites (both conditions must hold; both are deployment properties, not attacker-controlled at request time): - The jwt.decode allow-list mixes an HMAC algorithm with an asymmetric one, e.g. algorithms=["ES256", "HS256"] (the RFC 8725 footgun the guard exists to backstop). - The verification key is passed as raw PEM text/bytes on the non-PyJWK path, in a byte-form that cryptography's loader accepts but PyJWT's ispemformat regex does not recognize (marker-adjacent whitespace/indentation, CR-only line terminators, or the PEM folded to a single line). Such forms arise naturally from an indented YAML/JSON block, a single-line environment variable or JSON string, or a CR/LF round-trip through config tooling. The attacker additionally needs the public verification key, which is public by definition, and cryptography must be installed. The fix for CVE-2022-29217 rejects an asymmetric key handed to an HMAC algorithm, but only when ispemformat() recognizes the key as PEM. That…

    Recommended action: Upgrade to 2.14.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.com (1)osv.dev (2)Source checked Evidence →
  9. High, CVSS 7.4PyPIAmendedPublished

    PyJWT accepts public JWK containers as HMAC secrets

    CVE-2026-102273 · GHSA-w2cx-738m-mc7w

    Affected
    • PyPI pyjwt >= 2.13.0, <= 2.13.0
    Fixed in
    2.14.0· Vendor fix available
    Issue
    PyJWT 2.13.0 contains an incomplete defense against algorithm confusion when an application mixes symmetric and asymmetric algorithms in one verification path. A public RSA, EC, or OKP JWK can be accepted as an HMAC secret when it is wrapped in a JWKS object, nested in an array, or represented in another container form that does not expose a top-level kty member. Impact An attacker who knows the public key material can forge HS256/HS384/HS512 tokens if the application simultaneously: allows both HS and asymmetric algorithms; passes raw public JWK/JWKS JSON as key=; and uses that same value as the HMAC secret. This can allow forged JWT claims in affected application configurations. The issue does not affect applications that keep symmetric and asymmetric verification paths separate and follow PyJWT's algorithm-selection guidance. Fix status The fix is on master in commit 801cd12 (fix: reject public JWK container HMAC keys). HMACAlgorithm.preparekey now rejects public JWK…

    Recommended action: Upgrade to 2.14.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.com (1)osv.dev (2)Source checked Evidence →
  10. High, CVSS 7.4PyPIAmendedPublished

    PyJWT: PyJWKClient follows redirects when fetching JWKS

    CVE-2026-102267 · GHSA-9v7f-9g4p-ffgj

    Affected
    • PyPI pyjwt <= 2.13.0
    Fixed in
    2.14.0· Vendor fix available
    Issue
    PyJWT 2.13.0 PyJWKClient followed HTTP redirects while fetching a JWKS, without validating the redirect destination. A configured trusted endpoint could therefore redirect the client to a different host. Impact When an application uses PyJWKClient with caller-supplied request headers and an attacker can influence the configured endpoint's response, the redirected request could expose those headers and the redirected response could be used as authoritative key material. This could cause JWKS trust poisoning and, in affected mixed-configuration applications, forged JWT acceptance. The issue requires an attacker-influenced redirect from the configured JWKS endpoint; it is not triggered by a token kid alone. Affected versions PyJWT <= 2.13.0. Fix The issue is fixed on master in commit 0a795b8e1f6ef08f634aa7086fc41cc6d5ce3e56. PyJWKClient now disables automatic redirects for JWKS fetches. Regression tests verify that a redirect is rejected without contacting its destination, while…

    Recommended action: Upgrade to 2.14.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.com (1)osv.dev (2)Source checked Evidence →
  11. High, CVSS 7.4PyPIAmendedPublished

    PyJWT: Public keys in DER form are accepted as HMAC secrets, bypassing the CVE-2022-29217 guard

    CVE-2026-102271 · GHSA-p4g4-x82p-q773

    Affected
    • PyPI pyjwt >= 2.4.0, < 2.14.0
    Fixed in
    2.14.0· Vendor fix available
    Issue
    HMACAlgorithm.preparekey blocks asymmetric keys from being used as HMAC secrets by searching for text markers only. It looks for -----BEGIN and for an ssh- prefix. The same key in DER form is binary ASN.1 and has neither marker, so it passes the check and is used as an HMAC secret. An application that verifies tokens with an RSA or EC public key, and also allows HS256 with that same key, can be given a forged token. The attacker signs it with the public key, which is public. This is the key confusion problem CVE-2022-29217 was filed for, reachable again through a different encoding. The reach is smaller than the original CVE. The application must already be in that misconfiguration, and it must hold its public key as DER bytes rather than PEM. Details The guard is at jwt/algorithms.py:331: Both helpers are text matchers. Neither one parses the key. - jwt/utils.py:126, ispemformat, runs a regex for ----[- ]BEGIN ...----. - jwt/utils.py:141, issshkey, checks startswith against…

    Recommended action: Upgrade to 2.14.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.com (1)osv.dev (2)Source checked Evidence →
  12. High, CVSS 7.4PyPIAmendedPublished

    PyJWT BOM Bypass

    CVE-2026-102272 · GHSA-r6x4-923q-g947

    Affected
    • PyPI pyjwt >= 2.13.0, <= 2.13.0
    Fixed in
    2.14.0· Vendor fix available
    Issue
    Affected Package - Package: PyJWT (pyjwt on PyPI) - Repository: https://www.google.com/url?q=https://github.com/jpadilla/pyjwt&source=gmail&ust=1781794518474000&sa=E - Affected version: 2.13.0 - Vulnerability class: Algorithm confusion / patch bypass --- Root Cause PyJWT 2.13.0 introduced a guard in HMACAlgorithm.preparekey() (file jwt/algorithms.py, approximately line 344) to prevent RSA public key material from being used as an HMAC secret — the root cause of CVE-2026-48526. The guard uses bytes.lstrip() before calling startswith(b"{"): bytes.lstrip() with no argument removes only bytes in the ASCII whitespace set (\x20 \t \n \r \x0b \x0c). A UTF-8 BOM prefix (\xef\xbb\xbf) is not stripped, so stripped.startswith(b"{") returns False for any BOM-prefixed JWK JSON. The JWK detection block is never entered, and the RSA public key bytes are silently accepted as the HMAC-SHA256 secret. --- PoC Sketch (pseudocode — not a weaponized payload) --- Impact An unauthenticated network attacker…

    Recommended action: Upgrade to 2.14.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.com (1)osv.dev (2)Source checked Evidence →
  13. Medium, CVSS 5.3PyPIAmendedPublished

    PyJWT: PyJWKClient still amplifies unauthenticated JWKS fetches on unknown kid values (incomplete fix of CVE-2026-48524)

    CVE-2026-101917 · GHSA-2gx3-rcp4-g85q

    Affected
    • PyPI pyjwt <= 2.13.0
    Fixed in
    2.14.0· Vendor fix available
    Issue
    CVE-2026-48524 (GHSA-fhv5-28vv-h8m8, "PyJWKClient unbounded JWKS endpoint requests via attacker-controlled kid values (DoS)") was fixed in 2.13.0 by stopping fetchdata() from clearing the cache on a fetch error. That closed one amplification path but did not add the mitigation the advisory's title implies: there is still no rate-limit, negative-cache, or minimum-refresh-interval for unknown kids. At HEAD, getsigningkey(kid) (jwt/jwksclient.py:185-211), on any unknown kid, calls getsigningkeys(refresh=True), and refresh=True bypasses jwksetcache unconditionally and forces a fresh fetchdata(). The kid is read from the unverified token header (getsigningkeyfromjwt decodes with verifysignature=False), so no valid token and no authentication is required. lrucache does not cache the raised exception, so even the same unknown kid repeated re-fetches on every call. Affected pyjwt <= 2.13.0 (the latest release; the patched release for CVE-2026-48524). No fixed version yet. Proof of…

    Recommended action: Upgrade to 2.14.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.com (1)osv.dev (2)Source checked Evidence →
  14. Medium, CVSS 5.9PyPIAmendedPublished

    PyJWT: Malformed RSA JWK aborts parsing of an entire JWK Set

    CVE-2026-102274 · GHSA-w6j9-cwv2-h6wq

    Affected
    • PyPI pyjwt >= 2.9.0, <= 2.13.0
    Fixed in
    2.14.0· Vendor fix available
    Issue
    A malformed RSA JWK inside a JWK Set aborts parsing of the entire set instead of being skipped, because RSAAlgorithm.fromjwk can raise a plain ValueError that isn't caught by PyJWKSet's per-key error-skipping logic. Affected component / version - Package: PyJWT (PyPI, ecosystem pip) - Files: jwt/apijwk.py (PyJWK.init, PyJWKSet.init), jwt/algorithms.py (RSAAlgorithm.fromjwk) - Confirmed present in the master branch as of 2026-09-05 (commit 7144e4534c34810f4525dc4578a32addd8212cff, tag 2.13.0). Directly verified identical in tags 2.9.0, 2.10.0, 2.11.0, 2.12.0, 2.12.1, 2.13.0 -- the vulnerable call and the except PyJWTError guard are unchanged across all six releases. Not verified against any release prior to 2.9.0. Details PyJWKSet.init (jwt/apijwk.py:145-152) iterates each key in a JWK Set: PyJWK.init (apijwk.py:82) calls self.Algorithm.fromjwk(self.jwkdata) with no try/except of its own. For an RSA JWK, this dispatches to RSAAlgorithm.fromjwk (jwt/algorithms.py:539-586). When…

    Recommended action: Upgrade to 2.14.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.com (1)osv.dev (2)Source checked Evidence →
  15. Medium, CVSS 5.3PyPIAmendedPublished

    PyJWT: Unauthenticated DoS via unbounded Base64URL decoding of unused payload segment in b64=false detached JWS

    CVE-2026-48525 · GHSA-w7vc-732c-9m39

    Affected
    • PyPI pyjwt >= 2.8.0, <= 2.12.1
    Fixed in
    2.13.0· Vendor fix available
    Issue
    [!NOTE] Practical impact depends on whether request body-size limits are enforced upstream (proxy/web-server/framework). Deployments with typical body-size caps (≤2 MB) bound the amplifier significantly; deployments accepting larger token inputs are more exposed. When verifying detached JWS tokens using the unencoded-payload option ("b64": false, RFC 7797), PyJWT performs Base64URL decoding of the compact-serialization payload segment before enforcing the detached-payload rules. For b64=false, PyJWT later discards that decoded payload and replaces it with the caller-provided detachedpayload. In practice, this turns the middle segment into an attacker-controlled “work amplifier”: a remote client can supply an arbitrarily large Base64URL payload segment that forces CPU work + memory allocations even if the signature is invalid. This creates an unauthenticated DoS vector against any endpoint that verifies detached JWS using PyJWT. --- Affected Component(s) jwt/apijws.py PyJWS.decode() /…

    Recommended action: Upgrade to 2.13.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)github.com (2)Source checked Evidence →
  16. Medium, CVSS 4.2PyPIAmendedPublished

    PyJWKClient: missing scheme allowlist enables CVE-2024-21643-class SSRF + token forgery via file://, ftp://, data: schemes

    CVE-2026-48522 · GHSA-993g-76c3-p5m4

    Affected
    • PyPI pyjwt >= 2.0.0, <= 2.12.1
    Fixed in
    2.13.0· Vendor fix available
    Issue
    [!NOTE] The library does not directly return non-HTTP(S) URI contents to the attacker; the chained "plant a JWKS to forge tokens" scenario described in the original report requires additional application-layer flaws (attacker write access to a filesystem path, untrusted jku derivation) that this fix does not address. Severity is scored for the scheme-acceptance bug in isolation. Summary PyJWKClient passes its uri argument directly to urllib.request.urlopen() which uses Python stdlib's default OpenerDirector registering HTTPHandler, HTTPSHandler, FTPHandler, FileHandler, and DataHandler. There is currently no documented option to restrict which schemes PyJWKClient will fetch. If an application's jku URL ingestion path accepts attacker-influenced URLs (e.g., from JWT header, configuration file, OAuth flow parameter), the attacker can: 1. Cause PyJWKClient to read arbitrary local files via file:// (SSRF on local filesystem) — the file's contents are passed to json.load. 2. Cause…

    Recommended action: Upgrade to 2.13.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)github.com (2)Source checked Evidence →
  17. High, CVSS 7.4PyPIAmendedPublished

    PyJWT: Public-key JWK accepted as HMAC secret enables forged HS256 tokens when mixed families are allowed

    CVE-2026-48526 · GHSA-xgmm-8j9v-c9wx

    Affected
    • PyPI pyjwt < 2.13.0
    Fixed in
    2.13.0· Vendor fix available
    Issue
    [!NOTE] Exploitation requires a verifier configured with both symmetric and asymmetric algorithms in algorithms=[…] and a raw-JSON JWK as the key= argument, both contrary to documented usage, hence the High attack-complexity rating. Summary When the verifier is decoding JSON Web Tokens, while supporting both asymmetric and HMAC algorithms, the library does not validate use of JSON Web Keys in HMAC algorithm, allowing attacker to use the issuer public key as the secret key for HMAC algorithm. Details In JWT algorithm confusion attack, the verifier is mistakenly use of public key to be used as the shared secret in symmetric algorithms. In pyjwt case, when the verifier is supporting both HMAC with other asymmetric algorithm and mistakenly using the public key of the issuer to verify the token as demonstrated in the following example: jws.decode(token, key=rsajwkjson, algorithms=["HS256","RS256"])) An attacker who specifies in the token header to use HMAC, will cause the verifier to…

    Recommended action: Upgrade to 2.13.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)github.com (2)Source checked Evidence →
  18. Medium, CVSS 5.4PyPIAmendedPublished

    PyJWT: Algorithm allow-list bypass when decoding with PyJWK / PyJWKClient keys

    CVE-2026-48523 · GHSA-jq35-7prp-9v3f

    Affected
    • PyPI pyjwt >= 2.9.0, < 2.13.0
    Fixed in
    2.13.0· Vendor fix available
    Issue
    [!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.decodecomplete() 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.getsigningkeyfromjwt(...) flow. Summary PyJWT's PyJWK verification path allows a verifier-side algorithm allow-list bypass. In…

    Recommended action: Upgrade to 2.13.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)github.com (2)Source checked Evidence →
  19. Low, CVSS 3.7PyPIAmendedPublished

    PyJWKClient unbounded JWKS endpoint requests via attacker-controlled kid values (DoS)

    CVE-2026-48524 · GHSA-fhv5-28vv-h8m8

    Affected
    • PyPI pyjwt >= 2.0.0, <= 2.12.1
    Fixed in
    2.13.0· Vendor fix available
    Issue
    [!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.getsigningkey() 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, fetchdata() finally block clears the JWKS cache on network error. Root Cause jwt/jwksclient.py:172-198 - getsigningkey(kid) calls getsigningkeys(refresh=True) for unknown kids, bypassing TTL cache with no cooldown. jwt/jwksclient.py:120-122 - finally block writes None to cache on error, clearing valid data. Impact - DoS against JWKS endpoint (unlimited…

    Recommended action: Upgrade to 2.13.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)github.com (2)Source checked Evidence →
  20. High, CVSS 7.5PyPIAmendedPublished

    PyJWT accepts unknown crit header extensions

    CVE-2026-32597 · GHSA-752w-5fwx-jx9f

    Affected
    • PyPI pyjwt <= 2.11.0
    Fixed in
    2.12.0· Vendor fix available
    Issue
    PyJWT does not validate the crit (Critical) Header Parameter defined in RFC 7515 §4.1.11. When a JWS token contains a crit array listing extensions that PyJWT does not understand, the library accepts the token instead of rejecting it. This violates the MUST requirement in the RFC. This is the same class of vulnerability as CVE-2025-59420 (Authlib), which received CVSS 7.5 (HIGH). --- RFC Requirement RFC 7515 §4.1.11: The "crit" (Critical) Header Parameter indicates that extensions to this specification and/or [JWA] are being used that MUST be understood and processed. [...] If any of the listed extension Header Parameters are not understood and supported by the recipient, then the JWS is invalid. --- Proof of Concept Expected: jwt.exceptions.InvalidTokenError: Unsupported critical extension: x-custom-policy Actual: Token accepted, payload returned. Comparison with RFC-compliant library --- Impact - Split-brain verification in mixed-library deployments (e.g., API gateway using…

    Recommended action: Upgrade to 2.12.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)github.com (2)Source checked Evidence →
  21. Low, CVSS 2.1PyPIAmendedPublished

    PyJWT Issuer field partial matches allowed

    CVE-2024-53861 · GHSA-75c5-xw7c-p5pm

    Affected
    • PyPI pyjwt >= 2.10.0, <= 2.10.0
    Fixed in
    2.10.1· Vendor fix available
    Issue
    The wrong string if check is run for iss checking, resulting in "acb" being accepted for "abc". Details This is a bug introduced in version 2.10.0: checking the "iss" claim changed from isinstance(issuer, list) to isinstance(issuer, Sequence). Since str is a Sequnce, but not a list, in is also used for string comparison. This results in if "abc" not in "abcd": being checked instead of if "abc" != "abc":. PoC Check out the unit tests added here: https://github.com/jpadilla/pyjwt-ghsa-75c5-xw7c-p5pm Impact I would say the real world impact is not that high, seeing as the signature still has to match. We should still fix it.

    Recommended action: Upgrade to 2.10.1 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)github.com (2)Source checked Evidence →
  22. High, CVSS 7.4PyPIAmendedPublished

    Key confusion through non-blocklisted public key formats

    CVE-2022-29217 · GHSA-ffqj-6fqr-9h24

    Affected
    • PyPI pyjwt >= 1.5.0, < 2.4.0
    Fixed in
    2.4.0· Vendor fix available
    Issue
    Impact What kind of vulnerability is it? Who is impacted? Disclosed by Aapo Oksman (Senior Security Specialist, Nixu Corporation). PyJWT supports multiple different JWT signing algorithms. With JWT, an attacker submitting the JWT token can choose the used signing algorithm. The PyJWT library requires that the application chooses what algorithms are supported. The application can specify "jwt.algorithms.getdefaultalgorithms()" to get support for all algorithms. They can also specify a single one of them (which is the usual use case if calling jwt.decode directly. However, if calling jwt.decode in a helper function, all algorithms might be enabled.) For example, if the user chooses "none" algorithm and the JWT checker supports that, there will be no signature checking. This is a common security issue with some JWT implementations. PyJWT combats this by requiring that the if the "none" algorithm is used, the key has to be empty. As the key is given by the application running the…

    Recommended action: Upgrade to 2.4.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)github.com (2)Source checked Evidence →
  23. High, CVSS 7.5PyPIAmendedPublished

    PyJWT vulnerable to key confusion attacks

    CVE-2017-11424 · GHSA-r9jw-mwhq-wp62

    Affected
    • PyPI pyjwt < 1.5.1
    Fixed in
    1.5.1· Vendor fix available
    Issue
    In PyJWT 1.5.0 and below the invalidstrings check in HMACAlgorithm.preparekey does not account for all PEM encoded public keys. Specifically, the PKCS1 PEM encoded format would be allowed because it is prefaced with the string -----BEGIN RSA PUBLIC KEY----- which is not accounted for. This enables symmetric/asymmetric key confusion attacks against users using the PKCS1 PEM encoded public keys, which would allow an attacker to craft JWTs from scratch.

    Recommended action: Upgrade to 1.5.1 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)github.com (2)Source checked Evidence →