Problem Framing
JSON Web Tokens (JWTs) are a ubiquitous standard for securely transmitting information between parties as a JSON object, commonly used for authentication and authorization [1][2][3]. Their compact, self-contained nature and cryptographic signing provide a stateless approach to session management, making them attractive for modern distributed systems and APIs [1][4][5]. However, the flexibility and widespread adoption of JWTs also introduce a significant attack surface. Misconfigurations and improper implementation of JWT handling by developers can lead to critical vulnerabilities, allowing attackers to bypass authentication, escalate privileges, or impersonate users [6][7][2][1][4][3][8][9]. Understanding these threats is paramount for any application security professional working with or reviewing systems that utilize JWTs.
Core Mechanics
A JWT is fundamentally composed of three parts, separated by dots (.): a Header, a Payload, and a Signature [4][5][9].
- Header: This JSON object typically contains two parameters:
typ(token type, usuallyJWT) andalg(the signing algorithm used) [4][9][10]. Thealgparameter is critical as it dictates how the signature is verified.
- Payload: This JSON object contains the "claims," which are statements about an entity (typically the user) and additional metadata. Claims can be registered (standardized, like
issfor issuer,expfor expiration,subfor subject) or custom (private) [11][5][9]. Importantly, JWTs are typically encoded, not encrypted, meaning the payload is easily readable by anyone possessing the token [11][1][4][3][9][12]. Sensitive information should never be stored directly in the payload unless encrypted separately [3].
- Signature: The signature is generated by taking the encoded header, the encoded payload, and a secret (or private key), and signing them using the algorithm specified in the header [11][4][5]. This signature ensures the integrity of the token; any modification to the header or payload will invalidate the signature [11][9]. The server verifies the signature by recalculating it using its own secret/key and comparing it to the signature provided in the token. A match indicates the token is valid and has not been tampered with [11][9].
There are two primary categories of algorithms used for signing JWTs:
- Symmetric Algorithms (e.g., HS256, HS384, HS512): These use a single shared secret key for both signing and verification [11][4][13][9]. The security relies entirely on the secrecy and strength of this shared secret [11].
- Asymmetric Algorithms (e.g., RS256, ES256, PS256): These use a pair of keys: a private key for signing and a public key for verification [11][4][5][13][9]. The public key can be safely distributed, allowing any party to verify tokens without being able to forge them. The private key must remain secret [11][5].
Notable Techniques and Attack Vectors
The security of JWTs hinges on the correct implementation of signature verification and the secure management of signing keys. Many attacks exploit flaws in these areas.
Signature Verification Bypasses
A fundamental vulnerability arises from neglecting to verify the JWT's signature. This can occur in several ways:
- Failing to Verify the Signature (using
decode()instead ofverify()): Many JWT libraries offer adecode()function that simply parses the token's contents without verifying the signature. Developers may mistakenly use this instead of averify()function, which performs both decoding and signature validation [14][1][4][15][10][16]. This allows any token with a valid format to be accepted, regardless of its origin or integrity [14][1][15][16]. - The
alg: noneAlgorithm: The JWT specification defines analg: noneparameter for unsecured tokens [4][17][10][18][19]. If a server or library incorrectly allows this algorithm and fails to reject tokens with no signature, an attacker can craft a token withalg: none, remove the signature part, and submit it to gain unauthorized access by manipulating the payload [4][20][18][21][22][19][17][10][23][24]. Attackers can also bypass simple string matching of "none" by using case variations likeNone,NONE, ornOnE[11][4][19]. - Null Signature Attack: Similar to
alg: none, some libraries might accept tokens where the signature part is present but empty or malformed, effectively treating it as unsigned [18][23][24].
Algorithm Confusion (Key Confusion)
This class of attack exploits the JWT header's alg parameter. If the server's verification logic relies on the alg value provided in the token itself, rather than enforcing a pre-configured, expected algorithm, attackers can switch algorithms to forge tokens [25][26][18][27][28][29][8][19][30][31][24][12][23].
- RS256 to HS256 Confusion: A common attack involves changing the
algfrom an asymmetric algorithm likeRS256(which uses a private key to sign and a public key to verify) to a symmetric algorithm likeHS256(which uses a shared secret). Attackers can then obtain the server's public key (often publicly available), and use it as the HMAC secret to sign a forged token. Vulnerable libraries, trusting thealg: HS256header, will then use the public key as the secret for HMAC verification, leading to a bypass [11][25][26][20][18][27][28][29][8][19][15][30][32][31][12][23]. - Confusion within Asymmetric Families: Similar confusion can occur between different asymmetric algorithms (e.g., RS256 to PS256), though this may not always lead to a full bypass [30].
Key Management and Injection Vulnerabilities
Weaknesses in how signing keys are managed, referenced, or handled can also lead to JWT compromise.
- Weak Secret Keys (HS256): For symmetric algorithms like HS256, the security relies on the secrecy and strength of the shared secret. If the secret is weak, predictable, hardcoded, or leaked, attackers can brute-force or guess it offline and then forge any token they desire [11][26][20][18][5][8][15][33][34][13][10][35][36][37][24].
kidHeader Injection (Path Traversal/SQLi): Thekid(Key ID) header parameter can be used to specify which key the server should use for verification. If this parameter is not properly validated and sanitized, it can be vulnerable to path traversal (if used for file lookups) or SQL injection (if used in database queries) [11][38][20][18][39][40][41][42][12][43]. Attackers can leverage this to force the server to use arbitrary files (e.g.,/dev/nullfor an empty key) or sensitive files on the server as signing keys, or to execute arbitrary SQL queries [39][41][42][12][43].jkuandx5uHeader Injection: Thejku(JWK Set URL) andx5u(X.509 URL) header parameters specify URLs from which the server should fetch the public key for verification. If these URLs are not strictly validated against an allowlist, an attacker can point them to a server they control, hosting a malicious JWKS file with their own public key. They can then sign a forged token with their corresponding private key, which the vulnerable server will trust [44][45][46][12][47][24].- Embedded JWK (
jwkHeader): Thejwkheader parameter allows embedding the public key directly within the token. If the library incorrectly uses this embedded key for signature verification without proper checks, an attacker can inject their own public key [12][48].
Other Vulnerabilities
- Sensitive Data in Payload: JWT payloads are typically readable by anyone. Storing sensitive information like PII, passwords, or financial details in the payload without encryption is a critical security oversight [2][4][3][9][12].
- Improper Claim Validation: Missing or improperly validated claims (like
exp,nbf,aud,iss) can lead to replay attacks or cross-service token misuse [2][49][3][50][9][12]. For instance, a partial match for theissclaim in PyJWT versions 2.10.0 led to unauthorized access [49]. - Improper
critHeader Handling (CVE-2026-32597): Libraries failing to validate thecrit(Critical) header parameter, which lists extensions that must be understood, can lead to bypasses if unrecognized critical extensions are silently ignored [51]. - JWE Inner Token Vulnerabilities (CVE-2026-29000): When a JWE (encrypted JWT) contains an unsigned JWT (e.g.,
alg: none) in its inner payload, some libraries may fail to verify the inner signature, allowing for impersonation [52][53][54]. - Weak Encryption Key Lengths (CVE-2025-45768): Libraries not enforcing minimum key length requirements can expose applications to cryptographic attacks if weak keys are used [55].
Detection and Prevention
Securing JWT implementations requires a multi-layered approach, focusing on rigorous validation, secure key management, and up-to-date libraries.
Secure Verification Practices
- Algorithm Pinning: This is the most critical defense. Always explicitly specify the expected algorithm in your
verifyordecodecalls. Never trust thealgparameter from the token header to dictate the verification method [25][26][28][19][15][30][32][31]. Libraries should enforce this by requiring analgorithmsparameter or similar mechanism [25][26][28][19][32][31][56]. - Reject
noneAlgorithm: Unconditionally reject any token where thealgis set tonone, regardless of case variations. There is no legitimate production use case for unsigned JWTs [4][18][28][19][17][10][23][24]. - Reject Unknown Algorithms: Implement logic to reject tokens with unrecognized
algvalues, which protects against bypasses like those seen in HarbourJwt [38][28][19]. - Validate All Claims: Beyond the signature, rigorously validate critical claims:
iss(Issuer): Ensure it matches the expected issuer.aud(Audience): Ensure the token is intended for the current recipient service. This prevents token reuse across different services [2][49][3][50][9][12][57].exp(Expiration Time): Reject tokens that have expired.nbf(Not Before): Reject tokens that are not yet valid.jti(JWT ID): Use for replay prevention and to support token revocation [3][12].- Key Type and Algorithm Agreement: Implement checks to ensure the type of cryptographic key used matches the algorithm specified. For instance, an RSA public key should not be used as an HMAC secret [26][58][15][30][32][48][31][24].
- Validate
kidandjku/x5uParameters: If these parameters are used, implement strict validation. Forkid, use an allowlist of known key identifiers and do not use it for direct file system or database lookups [41][42]. Forjku/x5u, enforce a strict allowlist of trusted URLs or ignore these parameters altogether [45][46][30][12][47][24]. - Validate Token Format: Ensure the token conforms to the expected JWT structure (three base64url-encoded parts separated by dots).
Secure Key Management
- Use Strong, Random Keys: For symmetric algorithms (HS*), use cryptographically strong, randomly generated secrets with sufficient entropy (e.g., 32 bytes or more) [55][59][5][15][34][13]. Avoid predictable secrets like passwords or environment variables directly used as secrets.
- Key Rotation: Implement a strategy for regularly rotating signing keys to limit the impact of a potential compromise [59][5]. Use key versioning (
kid) to manage transitions smoothly [59]. - Separate Keys: If supporting multiple algorithms, use distinct keys for each. Never reuse keys across different algorithms or trust relationships [32].
- Protect Private Keys: For asymmetric algorithms, keep private keys strictly confidential. Protect them with file permissions, encryption, or a secure key management system (KMS) [59][32].
- Secure Key Storage: Avoid storing keys in code, plaintext configuration files, or version control systems. Use environment variables or secure secret management tools [14][59].
Secure Storage and Transmission
- HTTPS Everywhere: Always transmit JWTs over HTTPS to prevent eavesdropping and man-in-the-middle attacks [2][5][9].
- Secure Client-Side Storage: Prefer
HttpOnlyandSecureflags for cookies containing JWTs to mitigate XSS risks.SameSite=Strictadds CSRF protection [2][59][5][60][61]. AvoidlocalStorageandsessionStoragefor sensitive tokens if XSS is a concern, as these are accessible to JavaScript [2][60]. - Avoid JWTs in URLs: Do not transmit JWTs as URL parameters, as they can be logged by proxies, servers, or exposed via referrer headers [3]. Use the
Authorization: Bearerheader or POST request bodies instead [3][10][12][37].
Token Lifecycle Management
- Short Expiration Times: Issue tokens with short lifespans (e.g., 15-60 minutes) to minimize the window of opportunity for attackers if a token is compromised [62][59][5].
- Refresh Tokens: Implement refresh tokens for longer-lived sessions to maintain user experience without keeping access tokens valid for extended periods [62][59][5]. Manage refresh tokens securely, considering rotation and revocation [62].
- Revocation Mechanisms: For stateless JWTs, implement custom revocation mechanisms, such as maintaining a blocklist of revoked
jti(JWT ID) claims, or using very short-lived tokens coupled with refresh tokens [62][5].
Tooling
Several tools can aid in the analysis, testing, and exploitation of JWT vulnerabilities:
- jwt.io: A web-based tool for decoding and verifying JWTs [33][34][10][23]. Useful for initial inspection and understanding token structure.
- Burp Suite with JWT Editor Extension: Burp Suite, particularly with extensions like JWT Editor [63][48] and JOSEPH [63], is invaluable for intercepting, inspecting, editing, resigning, and exploiting JWTs. It allows for manual testing of various attacks and provides capabilities for managing signing keys [64][65][66][48].
- JWT\_Tool: A comprehensive Python-based toolkit for validating, forging, scanning, and tampering with JWTs. It supports numerous attacks, including
alg: none, key confusion,kidinjection, weak secret cracking, and more [33][67][37][56]. - jwt-pwn: A Python script for JWT cracking and signature bypasses [36].
- c-jwt-cracker: A C-based multi-threaded JWT brute-force cracker for finding HS* secrets [35].
- JWTAuditor: A 100% client-side JWT security testing platform that automates vulnerability detection, secret bruteforcing, and attack execution [24].
- jwt-hack: A high-performance toolkit for testing, analyzing, and attacking JWTs, with capabilities for decoding, encoding, verification, cracking, scanning, and server deployment [68].
- CookieMonster: A Go-based tool for auditing cookies, including JWTs, from various frameworks [69].
Recent Developments and Trends
The landscape of JWT vulnerabilities continues to evolve, with new CVEs emerging that highlight recurring implementation flaws. Recent trends include:
- Algorithm Confusion Dominance: Several critical CVEs in early 2026 (e.g., CVE-2026-22817 in Hono, CVE-2026-23993 in HarbourJwt, CVE-2024-33663 in python-jose) continue to exploit algorithm confusion, particularly the RS256-to-HS256 swap or mishandling of unknown algorithms [25][38][28][19][58][70]. This indicates that explicit algorithm pinning in verification logic remains a critical, yet sometimes overlooked, security measure [26][28][19][30][32].
kidandjku/x5uInjection Persistence: Vulnerabilities related to improper validation of thekid,jku, andx5uheaders continue to be discovered, allowing for key injection and signature bypasses [45][41][42][46][12][43][47].- Library Vulnerabilities: Security flaws are frequently found in popular JWT libraries themselves (e.g., PyJWT, python-jose, jsonwebtoken, pac4j-jwt), necessitating diligent dependency management and patching [51][55][52][71][49][53][58][72][32].
- Focus on Defensive Patterns: There's an increasing emphasis on defensive coding practices, such as explicitly pinning algorithms, validating all claims, and securely managing keys, as outlined in updated BCPs like draft-ietf-oauth-rfc8725bis [73][74][75].
Where to Go Deeper
For a more in-depth understanding and practical experience with JWT security, consider the following resources:
- OWASP JWT Cheat Sheet: A foundational resource for understanding JWT security best practices and common vulnerabilities [10][60].
- PortSwigger Web Security Academy: Offers comprehensive modules and deliberately vulnerable labs dedicated to JWT attacks, including signature bypasses,
alg: none, algorithm confusion, and key injection [31][76][64][46][66][48][63]. - JWT Pentesting Guides and Checklists: Resources from sources like Six2dez [77], Cyber Frogy [78][79], and 0xn3va [80] provide structured approaches to testing JWT implementations.
- Tool Documentation: Deep dives into the usage and capabilities of tools like
jwt_tool[33][37][56],jwt-pwn[36],c-jwt-cracker[35],jwt-hack[68], andJWTAuditor[24] are invaluable for practical exploitation and testing. - RFCs: For definitive details on the specifications, consult RFC 7519 (JWT), RFC 7515 (JWS), RFC 7516 (JWE), and RFC 7518 (JWA). RFC 8725 provides best current practices [73][74][75].
- Security Blogs and Write-ups: Numerous security blogs (e.g., infosecwriteups.com, medium.com, blog.randorisec.fr, sentinelone.com, bishopfox.com, pentesterlab.com, snyk.io) offer detailed analyses of specific JWT vulnerabilities and CVEs [6][14][81][51][25][38][55][26][4][49][82][83][84][44][20][18][39][27][21][28][29][8][85][40][53][19][58][72][15][86][87][88][50][45][41][42][89][90][33][91][92][93][16][94][46][17][54][9][30][70][95][32][43][67][23][47][35][36][37][65][66][48][31][76][24][96][97][98][99][57][100][101][102][69][60].