Understanding JWTs
JSON Web Tokens (JWTs) are a standardized, compact, and self-contained method for securely transmitting information between parties as a JSON object [1]. They are commonly used in modern web development for authentication and authorization, particularly in stateless architectures like APIs and microservices [1][2]. Unlike traditional session-based authentication that relies on server-side state, JWTs carry user information and permissions directly within the token, which is typically sent in the HTTP Authorization header as a Bearer token [3][2].
A JWT is composed of three parts, separated by dots (.): a header, a payload, and a signature. Each part is Base64Url-encoded [4].
- Header: Contains metadata about the token, such as the signing algorithm (
alg) and token type (typ) [4][1]. - Payload: Contains claims, which are statements about an entity (typically the user) and additional data. These can include registered claims (like
issfor issuer,expfor expiration time,audfor audience,iatfor issued at) or private claims defined by the application [1][2]. Crucially, JWTs are typically encoded, not encrypted, meaning sensitive data in the payload is visible to anyone holding the token [5][6]. - Signature: Generated by signing the encoded header and payload using a secret or private key, along with the algorithm specified in the header. This signature ensures the token's integrity and authenticity, preventing unauthorized modifications [4][1].
The signature is the critical security component. Without a valid signature, the token's claims cannot be trusted [5]. Various attacks exploit weaknesses in signature validation or the underlying cryptographic algorithms [7][8].
Core Mechanics and Security Implications
The fundamental security of a JWT relies on the integrity of its signature, which is generated using a specific algorithm and a secret or private key [1]. The server validates the JWT by recomputing the signature over the header and payload using its known key and comparing it to the signature provided in the token [5]. If the signature matches, the token is considered valid and untampered.
However, flaws in how JWTs are implemented and validated can introduce significant security risks:
- Signature Verification Failures: A common oversight is using a JWT library's decoding function (e.g.,
jwt.decode()) instead of its verification function (e.g.,jwt.verify()) [4][9]. This bypasses the signature check entirely, allowing any validly formatted token, or even a tampered one, to be accepted [10][11][9]. - Algorithm Confusion: The
algparameter in the JWT header specifies the signing algorithm. If the server blindly trusts this header parameter to select the verification method, an attacker can manipulate it. For instance, changingRS256(asymmetric) toHS256(symmetric) allows an attacker to sign a forged token using the server's publicly available RSA public key as the HMAC secret [12][13][14][15][16]. This bypasses authentication because the server attempts to verify the HMAC signature using the public key, which it possesses [17][18][15]. Similarly, acceptingnoneas an algorithm value allows for unsigned tokens, which are then accepted without cryptographic verification [4][19][20]. - Weak Secret Keys: For symmetric algorithms like
HS256, the security hinges on the secrecy and strength of the shared secret key. Weak, guessable, or hardcoded secrets can be brute-forced offline using the JWT's components, enabling attackers to forge valid tokens [5][3][21][22][23]. - Key Management Issues: Vulnerabilities can arise from how keys are managed and referenced. The
kid(Key ID) header parameter, intended to specify which key to use for verification, can be vulnerable to path traversal or SQL injection if not properly validated, potentially allowing attackers to use arbitrary files or database entries as signing keys [5][24][25][26][27]. Similarly, thejku(JWK Set URL) andx5u(X.509 URL) header parameters, if not strictly validated against a whitelist, can be exploited to point to attacker-controlled servers hosting malicious public keys [28][29][30][31]. - Token Lifecycle and Claims Validation: JWTs should have expiration times (
expclaim), and servers must validate these. Failure to do so can lead to replay attacks where expired tokens are still accepted [32][33][34]. Furthermore, claims likeiss(issuer) andaud(audience) should be validated to ensure tokens are from trusted sources and intended for the correct recipient, preventing token misuse across different services [32][8][34][35]. - Sensitive Data Exposure: JWT payloads are typically unencrypted. Storing sensitive information like personally identifiable information (PII) or credentials directly in the payload is a critical security risk [6][22].
Notable Techniques and Attack Vectors
Numerous techniques exploit JWT weaknesses, often targeting signature validation and algorithm handling. Many of these can be performed offline with specialized tools.
Signature Bypass and Tampering
alg:noneAttack: An attacker modifies thealgheader tononeand removes the signature. If the JWT library or server configuration permits unsigned tokens, the token is accepted as valid, allowing arbitrary payload modifications [5][4][3][19][20][36][37][38]. Case-insensitive variants likeNoneorNONEshould also be tested for [5][4][20].- Signature Stripping: Similar to
alg:none, but the algorithm in the header remains unchanged. If the server fails to validate the presence of a signature when one is expected, the token might still be accepted [19][36]. - Weak HMAC Secret Cracking: For HS256/HS384/HS512 tokens, attackers can recover the shared secret key using brute-force or dictionary attacks against the known token components. This allows them to forge arbitrary tokens [5][39][21][23]. Tools like
jwt_tool[40][41] andhashcatare effective for this [5][39][23]. kidHeader Injection (Path Traversal/SQLi): If thekidheader value is used to look up keys from the filesystem or database without proper validation, it can be exploited for path traversal or SQL injection, allowing the use of arbitrary files (e.g.,/dev/null, which can result in an empty key) or injected SQL to return valid keys or bypass verification [5][24][25][26][27][38].jku/x5uHeader Injection: If thejku(JWK Set URL) orx5u(X.509 URL) parameters are not strictly validated, an attacker can point them to a URL they control, hosting a JWKS file containing their own public key. The server then uses this attacker-provided public key to verify a token signed by the attacker's private key [28][29][30][31][16].- Psychic Signatures (CVE-2022-21449): In certain Java versions, ECDSA signature verification could be bypassed by manipulating specific bytes in the signature, allowing arbitrary payload changes without knowledge of the private key [37].
Algorithm Confusion
- RS256 to HS256 Confusion: This is a prevalent attack where an attacker crafts a token with
alg: HS256and signs it using the server's RS256 public key as the HMAC secret. Vulnerable libraries, which use the header'salgto select the verification function, will then use the public key as the symmetric secret for HMAC verification, thus accepting the forged token [5][12][17][13][14][15][16][42][43]. - ECDSA to HS256 Confusion: Similar to the RS256 confusion, but involves switching from an ECDSA algorithm (e.g.,
ES256) toHS256and using the ECDSA public key as the HMAC secret [44][45]. - Unknown Algorithm Bypass: Libraries that do not explicitly reject unknown algorithm values in the header can be bypassed. The library might return an empty signature or mishandle the unknown algorithm, leading to verification failure and acceptance of the forged token [46][14].
Key Confusion and Injection
kidHeader Injection: As mentioned above, vulnerabilities in how thekidparameter is processed can lead to path traversal, SQL injection, or command injection, allowing control over the key used for verification [5][24][25][26][27].- Embedded JWK (
jwkheader): Thejwkheader parameter can directly embed a public key. If the library incorrectly uses this embedded key for signature verification instead of a trusted, pre-configured key, attackers can embed their own public key and sign tokens accordingly [47][31].
Other Vulnerabilities
- JWTs within JWE: In cases where a JWT is first decrypted (JWE) and then verified (JWS), some libraries might fail to validate the signature of the inner JWT if it's unsigned (e.g.,
alg:none) [48][49][50][36]. - Claim Tampering: If signature validation is flawed, attackers can directly modify claims in the payload to elevate privileges, change user roles, or impersonate other users [5][3][51][27][38].
- Weak Secret Management: Secrets used for symmetric encryption should be cryptographically strong and managed securely, ideally not hardcoded or exposed in client-side code [34][22].
aud(Audience) Claim Validation: Failure to validate theaudclaim can allow tokens intended for one audience to be used by another, potentially enabling cross-service relay attacks [8][52][53][31].iss(Issuer) Claim Validation: Similarly, improper validation of theissclaim can lead to accepting tokens from unintended or malicious issuers [8][54][53].
Detection and Prevention
Securing JWT implementations requires a multi-layered approach, focusing on robust validation, secure key management, and adherence to best practices.
Signature Validation and Algorithm Enforcement
- Explicitly Pin Algorithms: Always specify the expected signing algorithm (e.g.,
RS256) in the verification call. Never rely on thealgheader from the token to determine the algorithm. Reject tokens with unknown or disallowed algorithms [12][17][34][14][54][53][55][16]. - Reject
alg:noneand Unknown Algorithms: Explicitly reject tokens where the algorithm is set tonone, or any algorithm not on an allowlist. This prevents signature bypasses and algorithm confusion attacks [4][20][53]. - Validate Key Types and Algorithms: Ensure the type of cryptographic key used (e.g., RSA public key, HMAC secret) matches the expected algorithm. Libraries should ideally perform this check internally, or it should be implemented as a defense-in-depth measure [17][56][53].
- Do Not Trust
jku,x5u,kidParameters Without Validation: Implement strict allowlists for URLs referenced byjkuandx5uparameters, or ignore them entirely. Validatekidvalues against a predefined mapping and reject values that appear to be path traversal or injection attempts [5][28][29][25][26][30][31][47]. - Never Use
decode()withoutverify(): Always use the library's verification function that checks the signature before decoding the payload [4][9][37].
Key Management
- Use Cryptographically Strong Keys: For symmetric algorithms (HS), use long, random, and high-entropy secret keys. For asymmetric algorithms (RS, ES*), use adequately sized keys (e.g., 2048-bit RSA or larger) [57][34][21].
- Secure Key Storage: Store secrets and private keys securely, ideally using environment variables or a dedicated secrets management system. Never commit them to version control systems [1][34].
- Regular Key Rotation: Implement a strategy for rotating cryptographic keys to limit the impact of potential compromises. Key versioning can help manage transitions gracefully [34][22].
- Centralized Key Management: Especially in distributed systems, a centralized and secure key management solution is crucial [53].
Token Lifecycle and Claim Validation
- Short Token Expiration: Set reasonably short expiration times (e.g., 15-60 minutes for access tokens) to minimize the window of opportunity if a token is compromised [32][33][34][22].
- Validate
exp,nbf,iat,iss,aud, andjtiClaims: Always verify that tokens are not expired (exp), not used before they are valid (nbf), and were issued at a reasonable time (iat). Crucially, validate the issuer (iss) and audience (aud) to prevent tokens from being trusted by the wrong parties or services [32][8][33][34][53][55][31][35]. Use unique token identifiers (jti) for revocation purposes [34][22]. - Implement Token Revocation: Since JWTs are stateless, revocation requires additional mechanisms. Common strategies include maintaining a blocklist of revoked token identifiers (
jti), using very short token lifespans combined with refresh tokens, or token rotation [33][34][22].
Secure Transmission and Storage
- Use HTTPS Exclusively: Always transmit JWTs over TLS-encrypted connections to prevent eavesdropping and man-in-the-middle attacks [32][6][22].
- Secure Client-Side Storage: Avoid storing JWTs in
localStorageorsessionStoragedue to XSS risks. PreferHttpOnlyandSecurecookies, coupled withSameSite=Strictfor CSRF protection [32][34][22][58]. - Avoid Sensitive Data in Payloads: Do not store sensitive or PII in JWT payloads. If necessary, consider encryption (JWE) or using opaque tokens that reference server-side data [6][22][53].
Tooling
A variety of tools can assist in identifying and exploiting JWT vulnerabilities:
- jwt.io: An online encoder/decoder and validator, useful for inspecting and manipulating JWTs [5][3][39][30][38].
- jwt_tool: A Python-based toolkit for testing, tweaking, and cracking JWTs, supporting various attacks and fuzzing capabilities [59][40][60][41][61].
- jwt-hack: A high-performance toolkit for testing, analyzing, and attacking JWTs, supporting decoding, encoding, verification, cracking, scanning, and more [62].
- jwtXploiter: A security testing tool for JWTs, capable of tampering, exploiting header claims, verifying tokens, and performing key confusion attacks [63].
- c-jwt-cracker: A C-based multi-threaded JWT brute-force cracker for recovering HS256/HS384/HS512 secrets [23].
- jwt-pwn: A collection of scripts for JWT security testing, including crackers and payload generators [64].
- JWTAuditor: A client-side JWT security testing platform with advanced analysis, secret bruteforcing, JWT editing, and attack modules [43].
- Burp Suite Extensions:
- JWT Editor: A Burp Suite extension for detecting, editing, signing, verifying, encrypting, and decrypting JWTs, also facilitating common attacks [65][66][47].
- JWT Scanner: A Burp Suite extension for automatically detecting JWT vulnerabilities [67].
- JOSEPH: A Burp Suite extension for testing JOSE applications, including JWTs [66][47].
- Hashcat: A powerful password cracking tool that can be used with specific modes (e.g.,
-m 16500) to crack HMAC-SHA secrets from JWTs [5][39][23].
Recent Developments
The JWT ecosystem continues to evolve, with new vulnerabilities and attack vectors being discovered. Recent CVEs in 2025 and 2026 highlight ongoing issues with algorithm confusion in various JWT libraries and frameworks across different programming languages [14][54]. For instance, CVE-2026-22817 affected Hono for trusting the alg header [12][14], and CVE-2026-23993 impacted HarbourJwt with an unknown algorithm bypass [46][14]. Vulnerabilities related to improper validation of header parameters like kid and jku also remain prevalent [29][25][26]. The IETF continues to update best practices, such as in draft-ietf-oauth-rfc8725bis, reflecting new threats discovered since RFC 8725 [8][68]. Awareness of these evolving threats and library updates is critical for maintaining secure JWT implementations.
Where to Go Deeper
For a comprehensive understanding of JWT security and exploitation, explore the following resources:
- OWASP JWT Cheat Sheet: A foundational resource for JWT security principles and best practices [37][58].
- PortSwigger Web Security Academy: Offers detailed explanations and deliberately vulnerable labs for practicing JWT attacks [16][42].
- JWT Pentest Checklists: Resources from practitioners like Cyber Frogy and Chintan Gurjar provide structured approaches to testing JWT implementations [69][70].
- Blogs and Write-ups: Numerous security blogs and articles offer in-depth analysis of specific JWT vulnerabilities, attack techniques, and tool usage. Key authors and platforms include InfosecWriteups, Medium, Snyk, SentinelOne, and the personal blogs of security researchers [7][5][10][59][32][1][12][46][17][4][3][13][14][51][54][11][29][36][15][37][60][16][43].
- Tool Documentation: Understanding the capabilities and usage of tools like
jwt_tool,jwt-hack, and Burp Suite extensions is essential for practical testing [62][40][61][41][65][47]. - RFC Standards: For definitive technical details, consult RFC 7519 (JWT), RFC 7515 (JWS), RFC 7516 (JWE), RFC 7518 (JWA), and RFC 8725 (JWT BCP) [8][68][55][31].