Problem Framing
JSON Web Tokens (JWTs) have become a ubiquitous standard for securely transmitting information between parties, particularly in authentication and authorization contexts [1][2]. Their stateless nature and self-contained structure offer significant advantages in modern distributed systems and microservices architectures [1][3]. However, the widespread adoption of JWTs has also exposed a variety of security vulnerabilities stemming from their implementation and usage. This guide aims to provide an in-depth, practitioner-focused overview of JWT security, targeting experienced application security professionals.
Core Mechanics
A JWT is a compact, URL-safe representation of claims to be transferred between two parties. It is composed of three distinct parts, separated by dots (.): a header, a payload, and a signature [4][1][2][5].
- Header: This section, typically JSON, defines metadata about the token, most importantly the signing algorithm (e.g.,
HS256,RS256) and the token type (typ, usuallyJWT) [1][2]. Thealgparameter is critical as it dictates how the signature should be verified [6][7][8]. - Payload: This JSON object contains the "claims," which are statements about an entity (typically the user) and additional data. Claims can be registered (standardized), public (custom, registered), or private (custom, specific to parties) [1][2]. Sensitive information should never be stored in the payload, as it is merely base64-encoded and not encrypted [9][10].
- Signature: The signature is generated by taking the encoded header, the encoded payload, a secret, and the algorithm specified in the header, then signing them [1]. This signature guarantees the token's integrity – that it has not been tampered with since issuance [2][5].
The structure is represented as HEADER.PAYLOAD.SIGNATURE, where each part is Base64URL-encoded [2]. A key characteristic is that the header and payload are encoded, not encrypted, meaning they are human-readable if decoded [6]. The signature verification process is paramount; failure to do so correctly is the root cause of many JWT vulnerabilities [11][4][2][12][13].
Notable Techniques and Vulnerabilities
JWT vulnerabilities often exploit flaws in how the signature is verified, how algorithms are handled, or how keys are managed. The following are some of the most prevalent attack vectors:
Signature Verification Flaws
The integrity of a JWT relies entirely on the signature. If this verification is skipped or implemented incorrectly, attackers can manipulate the token.
- Failing to Verify the Signature: This is the most critical and common flaw. Libraries often provide separate
decode()(which only decodes) andverify()(which decodes and verifies the signature) functions. Developers may mistakenly usedecode(), leading to unchecked token acceptance [1][2][14][15]. - The "None" Algorithm: The JWT standard supports an
algvalue of"none", indicating an unsigned token. Vulnerable implementations may accept tokens where the header specifies"alg": "none"and the signature is omitted or empty [6][2][16][17][18][19][14][20][15][21][22]. Attackers can often bypass simple blocklists by using case variations (e.g.,None,NONE) [6][2]. - Null Signature Attack: Similar to the "none" algorithm, this occurs when the server accepts tokens with a valid header but an empty or invalid signature, especially if the algorithm is not explicitly rejected [17][14][22].
- ECDSA "Psychic Signatures" (CVE-2022-21449): A specific vulnerability in certain Java versions allowed attackers to forge ECDSA signatures by manipulating token data and replacing the signature with a specific value, bypassing verification [15].
Algorithm Confusion and Key Management Issues
These attacks exploit how JWT libraries handle the selection and usage of cryptographic algorithms and keys.
- Algorithm Confusion (RS256 to HS256): This is a prevalent attack where an attacker modifies the token's
algheader from an asymmetric algorithm (likeRS256) to a symmetric one (likeHS256). The attacker then signs the token using the server's public key as the HMAC secret. If the JWT library or application trusts thealgheader and doesn't enforce algorithm-key type matching, it will incorrectly use the public key as a symmetric secret for verification, leading to forgery [6][7][23][17][8][19][24][25][26][22][27]. Libraries that fail to explicitly specify the expected algorithm in the verification call are vulnerable [7][23][8][19][25][27]. Variations exist for other asymmetric/symmetric pairs like ES256 to HS256 [28][26]. - Weak Symmetric Keys (HMAC Secrets): If JWTs are signed with HMAC algorithms (
HS256,HS384,HS512), the security relies on the secrecy and strength of the shared secret key. Weak, guessable, or hardcoded secrets can be brute-forced offline using tools like Hashcat or dedicated JWT crackers [6][16][14][29][30][31][32][33][34]. - Key Injection (
kidHeader): Thekid(Key ID) header parameter specifies which key to use for verification, especially in systems with multiple keys. If thekidvalue is used insecurely (e.g., directly in file paths or database queries), it can be vulnerable to injection attacks.- Path Traversal: An attacker can manipulate the
kidparameter to traverse the file system and use the content of an arbitrary file as the signing key [6][35][36][37][21][22]. This can even lead to using files with empty content (like/dev/null) to bypass verification [35][36][21]. - SQL Injection: If the
kidparameter is used in database queries without proper sanitization, it can lead to SQL injection, allowing attackers to retrieve arbitrary keys or bypass key lookups [5][38][21].
- Path Traversal: An attacker can manipulate the
- JWKS/X5U Injection (
jku,x5uHeaders): Thejku(JWK Set URL) andx5u(X.509 URL) header parameters specify where to fetch public keys. If these URLs are not strictly validated against an allowlist, an attacker can point them to a malicious server hosting their own JWKS, allowing them to sign forged tokens with their private key [39][40][41][25][42][22][43]. - Embedded JWK (
jwkHeader): Thejwkheader parameter allows embedding the public key directly in the token. Some libraries might mistakenly use this embedded key for verification, allowing attackers to inject their own keys [44][45].
Claim-Related Vulnerabilities
While the signature protects the token's integrity, flaws in how claims are processed can still lead to security issues.
- Claim Tampering: After bypassing signature verification or exploiting an algorithm confusion, an attacker can modify claims in the payload to gain elevated privileges (e.g., changing
"role": "user"to"role": "admin") [11][4][5][44][34]. - Issuer (
iss) and Audience (aud) Validation Issues: Incorrect validation of theissclaim can allow tokens from unintended issuers, while improperaudvalidation can permit token replay across different services [9][10][8][19][46][47]. PyJWT versions 2.10.0 exhibited partial string matching for theissclaim, leading to potential bypasses [48]. - Expiration (
exp) and Not Before (nbf) Claim Bypass: While critical for limiting token validity, if these claims are not properly checked by the server, expired or pre-activated tokens might be accepted [9][49][5][15][50].
Library-Specific Vulnerabilities
Various JWT libraries have had specific vulnerabilities discovered:
- PyJWT: CVE-2026-32597 (Improper validation of the
critheader parameter) [51]. CVE-2025-45768 (Weak encryption key length enforcement) [52]. CVE-2024-53861 (issfield partial match) [48]. - python-jose: CVE-2024-33663 (Algorithm confusion with OpenSSH ECDSA keys) [28][24].
- pac4j-jwt: CVE-2026-29000 (Authentication bypass in
JwtAuthenticatorfor JWEs with unsigned inner tokens) [53][54]. - Hono: CVE-2026-22817 (Algorithm confusion, trusting
algheader) [7][8][19]. - HarbourJwt: CVE-2026-23993 (Unknown algorithm bypass) [35][8][19].
- jsonwebtoken (Node.js): CVE-2022-23529 (Retracted, but related to insecure usage and specific prerequisites for potential RCE) [55]. Vulnerabilities related to algorithm confusion existed before version 4.2.2 [56][27].
- fast-jwt: CVE-2026-34950 (Incomplete fix for algorithm confusion due to regex anchor issues) [57].
- python-jwt: CVE-2022-39227 (Token forgery due to inconsistency between parsers) [58].
It's crucial to keep JWT libraries updated to the latest patched versions [59][51][57][7][53][35][52][58][48][28][54][19][24][26][60].
Detection and Prevention
Securing JWT implementations requires a multi-faceted approach focusing on robust validation, secure key management, and adherence to best practices.
Key Validation Principles
- Algorithm Pinning: This is the most critical defense against algorithm confusion attacks. Explicitly specify the expected algorithm(s) in your JWT verification code. Never allow the library to infer the algorithm from the token's header. Use an allowlist of algorithms and reject any token with an unexpected or unsupported algorithm [7][23][61][8][19][25][62][27].
- Reject "none" and Unknown Algorithms: Always explicitly reject tokens where the
algheader is"none"or an unrecognized value. There is no legitimate production use case for unsigned JWTs or tokens with arbitrary algorithms [35][2][61][8][19][14][20][62][15][22][34]. - Strict Signature Verification: Ensure that your JWT library's
verify()function is used, not justdecode(). All incoming tokens must have their signatures validated [4][2][14][13][15][33][34]. - Key Type and Algorithm Agreement: Implement defense-in-depth by verifying that the provided key type matches the expected algorithm. For instance, an RSA public key should not be used as an HMAC secret [23][24][25][45][27].
- Validate Claims: Beyond signature verification, rigorously validate registered claims like
iss(issuer),aud(audience),exp(expiration time), andnbf(not before). Reject tokens that don't meet these criteria [9][49][61][8][5][19][46][13][62][15][42][22]. kidand JWKS URL Validation: When using header parameters likekid,jku, orx5uto fetch keys, implement strict validation. Use an allowlist for JWKS URLs and sanitizekidvalues to prevent path traversal or injection attacks. Consider disabling these header parameters entirely and configuring keys directly [6][35][39][36][5][40][37][38][41][25][42][21][22][43].
Secure Key Management
- Strong, Unique Secrets/Keys: Use cryptographically strong, randomly generated keys and secrets. Avoid predictable values or information derived from environment variables or application names [6][52][61][30][63][13]. For asymmetric keys, ensure they meet recommended length requirements (e.g., 2048 bits for RSA) [52][61].
- Key Rotation: Implement a regular key rotation strategy to limit the impact of potential key compromise. Use key versioning to support graceful transitions [61][10].
- Secure Storage of Keys: Private keys and symmetric secrets must be stored securely and never exposed in code repositories or client-side code [4][61][10][55].
Token Lifecycle and Storage
- Short Token Expiration: Configure JWTs with short expiration times (e.g., 15-60 minutes for access tokens) to minimize the window of vulnerability if a token is compromised [9][49][61][10][5][62][50].
- Refresh Tokens: Use separate, longer-lived refresh tokens to maintain user sessions without excessively long access token lifespans. Implement refresh token rotation for added security [49][61][10].
- Revocation Mechanisms: Since JWTs are stateless, revocation before expiration requires custom solutions like token blocklists (using the
jticlaim) or token versioning [49][61][10][50]. - Secure Storage: Store JWTs securely on the client-side. HttpOnly and Secure cookies are generally preferred for web applications, with
SameSite=Strictfor CSRF protection. Avoid storing sensitive tokens inlocalStoragedue to XSS risks.sessionStorageoffers slightly better security but is still vulnerable to XSS [9][61][10][50][64]. - HTTPS Everywhere: Always transmit JWTs over encrypted channels (HTTPS) to prevent eavesdropping and man-in-the-middle attacks [9][10][3].
Tooling
A variety of tools can assist in analyzing, testing, and exploiting JWT vulnerabilities:
- jwt.io: An indispensable online tool for decoding, verifying, and debugging JWTs [16][29][15][22]. It runs client-side, so tokens do not leave the browser [6].
- jwt_tool: A Python-based toolkit for testing, tweaking, cracking, and attacking JWTs. It supports numerous exploits, including
alg:none, algorithm confusion, and weak secret cracking [65][66][26][33][60]. - jwt-hack: A high-performance toolkit written in Rust for testing, analyzing, and attacking JWTs, with support for compression and JWE decoding [65].
- jwt-cracker (C): A multi-threaded JWT brute-force cracker for cracking HMAC secrets [31].
- JWTAuditor: A 100% client-side JWT security testing platform offering advanced analysis, secret bruteforcing, editing, and exploit modules [43].
- Burp Suite Extensions:
- Hashcat: A powerful password cracking utility that can be used to brute-force JWT secrets (mode 16500) [6][63][32][34].
- CookieMonster: A Go-based tool for detecting issues with various stateless authentication tokens, including JWTs [70].
Recent Developments
The JWT landscape continues to evolve with new vulnerabilities and attack vectors being discovered. Recent developments highlight persistent issues and emerging threats:
- Algorithm Confusion Dominance: The problem of algorithm confusion, particularly the RS256-to-HS256 swap, remains a significant threat, with multiple CVEs reported in early 2026 affecting various languages and frameworks like Hono (CVE-2026-22817) and HarbourJwt (CVE-2026-23993) [7][35][8][19]. These CVEs underscore the critical need for explicit algorithm pinning [8][19].
- JWE Vulnerabilities: Flaws in handling encrypted JWTs (JWEs) have also surfaced. CVE-2026-29000 in pac4j-jwt allowed authentication bypass by wrapping an unsigned inner JWT within a valid JWE [53][54].
- Crit Parameter Validation Issues: CVE-2026-32597 in PyJWT highlighted issues with improper validation of the
crit(Critical) Header Parameter, allowing tokens with unrecognized critical extensions to be accepted [51]. - Continued Focus on Key Management: Vulnerabilities related to
kidparameter injection (path traversal, SQLi) and JWKS URL validation (jku/x5u) continue to be discovered, emphasizing the need for robust input validation and key retrieval practices [35][39][36][5][40][37][38][21][22]. - Library-Specific CVEs: Ongoing discovery of vulnerabilities in popular libraries like PyJWT, python-jose, and fast-jwt indicates that even well-established tools can have exploitable flaws [57][52][48][28][24].
- RFC 8725bis: Updates to JWT Best Current Practices (BCP) are ongoing, reflecting lessons learned from past vulnerabilities and providing updated guidance for secure implementation [71][72][73].
Where to Go Deeper
For a deeper understanding and hands-on practice with JWT vulnerabilities and attacks, the following resources are highly recommended:
- OWASP JWT Cheat Sheet: A foundational resource for understanding JWT security concepts and best practices.
- PortSwigger Web Security Academy: Offers comprehensive guides and deliberately vulnerable labs for practicing JWT attacks, including algorithm confusion and signature bypasses [27][34].
- PentesterLab: Provides hands-on labs for exploring various JWT vulnerabilities and attack techniques [14][26].
- Six2dez's JWT Pentest Book: A practical guide covering JWT exploitation techniques [74].
- Intigriti's JWT Exploitation Guides: Detailed articles and walkthroughs on exploiting JWT vulnerabilities [75][44].
- GitHub Repositories: Many tools and PoCs are available on GitHub, offering code examples and practical exploit implementations [65][31][32][60][45][43].
- RFC 8725 (JWT Best Current Practices): The official specification and best practice guidelines for JWT implementation [71][72][73].