Table of Contents
- What is JWT?
- Structure of JWT
- Authentication Flow
- What are JWT attacks?
- Exploiting Flawed Signature Verification
- Brute-forcing Weak Secret Keys
- JWT Header Parameter Injections
- Algorithm Confusion
- Resources

What is JWT (JSON Web Token)?
an open standard (RFC 7519) used to securely transfer information between parties as a JSON object. It is compact, self-contained, and commonly used to send information (“claims”) about users as part of authentication, session handling, and access control mechanisms.
Example JWT:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. ---> Header
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ ---> Payload
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c ---> Signature
Structure of JWT
- Header: Contains metadata about the token, such as the algorithm used (HS256, RS256).
- Payload: Contains the claims or data (user information, roles). This part is base64-encoded and not encrypted.
- Signature: A hash of the header and payload signed with a secret key or private key.
-
Symmetric vs. Asymmetric Signing
Symmetric (HS256): Uses the same secret key to sign and verify must be kept secure. Asymmetric (RS256): Uses a private key to sign (kept secret by the server) and a public key to verify (can be shared). More secure for distributed systems.
-
The Authentication Flow using JWT
- User submits credentials ( username and password) to the server.
- Server verifies credentials against a database or identity provider.
- If credentials are valid, server generates a JWT:
- Header: Specifies algorithm (
{"alg": "HS256", "typ": "JWT"}). - Payload: Contains claims (
sub,iat,exp,role). - Signature: Signs header and payload using a secret key (for HMAC) or private key (for RSA).
- Encodes header, payload, and signature in Base64, joining them with dots (
.).
- Header: Specifies algorithm (
- Server sends JWT to client ( in HTTP response, often as a cookie or in Authorization header).
- Client stores JWT (in local storage, session storage, or cookie).
- Client includes JWT in subsequent requests (in
Authorization: Bearer <JWT>header). - Server Validates JWT
- Server verifies:
- Signature using secret key (HMAC) or public key (RSA).
- Payload claims (
expfor expiration,issfor issuer).
- If valid, grants access to requested resources.
- Server verifies:
What are JWT attacks?
involve a user sending modified JWTs to the server in order to achieve a malicious goal. Typically, this goal is to bypass authentication and access controls by impersonating another user who has already been authenticated
Exploiting flawed JWT signature verification
The server doesn’t actually know anything about the original contents of the token, or even what the original signature was. Therefore, if the server doesn’t verify the signature properly, there’s nothing to stop an attacker from making arbitrary changes to the rest of the token.
-
Accepting arbitrary signatures
JWT libraries typically provide one method for verifying tokens and another that just decodes them.
For example, the Node.js library
jsonwebtokenhasverify()anddecode().Occasionally, developers confuse these two methods and only pass incoming tokens to the
decode()method. This effectively means that the application doesn’t verify the signature at all.Mitigation: Never trust the payload until the signature is successfully validated
-
Accepting tokens with no signature
his tells the server which algorithm was used to sign the token and, therefore, which algorithm it needs to use when verifying the signature.
JWTs can be signed using a range of different algorithms, but can also be left unsigned. In this case, the
algparameter is set tonone, which indicates a so-called “unsecured JWT”. Due to the obvious dangers of this, servers usually reject tokens with no signature. However, as this kind of filtering relies on string parsing, you can sometimes bypass these filters using classic obfuscation techniques, such as mixed capitalization and unexpected encodings.-
Exploiting the “none” algorithm
- Decode the JWT
- Modify the Algorithm to “none” delete signature
noneNoneNONEnOnE
- Send the Modified JWT: try to add = end of jwt
-
Mitigations
- Explicitly disable the “none” algorithm in your JWT library configuration
- Do not rely on defaults, enforce algorithm allowlists like
RS256orHS256
-
Brute-forcing weak secret keys
Brute-forcing secret keys using hashcat
hashcat -a 0 -m 16500 <jwt> <wordlist>
forge JWTs
JWT header parameter injections
-
Injecting self-signed JWTs via the jwk parameter
jwk(JSON Web Key) - Provides an embedded JSON object representing the key.-
Exploit this vulnerability explain
- Generates their own RSA key pair.
- Creates a JWT with a forged payload (
"user": "admin"). - Includes their public key in the header under the
jwkfield: - Signs the token using their private key.
- Sends the token to the vulnerable service.
-
Exploit In Burp
load the JWT Editor extension from the BApp store.
- In Burp Repeater, change edit jwt.
- Go to the JWT Editor Keys tab in Burp’s main tab bar.
- Click New RSA Key.
- In the dialog, click Generate to automatically generate a new key pair, then click OK to save the key. Note that you don’t need to select a key size as this will automatically be updated later.
- Burp Repeater and switch to the extension-generated
JSON Web Tokentab. - At the bottom of the JSON Web Token tab, click Attack, then select Embedded JWK. When prompted, select your newly generated RSA key and click OK.
- In the header of the JWT, observe that a
jwkparameter has been added containing your public key. - Send the request to test how the server responds.
Mitigation: Never accept keys from the token itself
-
-
Injecting self-signed JWTs via the jku parameter
jku(JSON Web Key Set URL) - Provides a URL from which servers can fetch a set of keys containing the correct key.- To exploit this vulnerability
- Generate their own RSA key pair.
- Host the public key on a server they control, either:
- As a JWK set (for
jku) - As an X.509 certificate (for
x5u)
- As a JWK set (for
- Create a JWT with:
"alg": "RS256""jku": "https://attacker.com/jwks.json"or"x5u": "https://attacker.com/cert.pem"
- Sign the token using their private key.
- Send the forged token to the target application.
- Mitigations
- Do not trust keys from arbitrary
jkuorx5uURLs. - Implement an explicit allowlist of trusted domains for JWK and cert loading.
- Do not trust keys from arbitrary
-
Injecting self-signed JWTs via the kid parameter
the
kidheader parameter tells the server which public key to use to verify the JWT’s signature. Regardless of the location of the public key, the server generally looks for one that has the samekidas the one present in the JWT. However, depending on how the server manages the value of thekid, classic vulnerabilities such as SQL injection or path traversal can occur.- Exploiting IT
- Verify
kidin Header: Check if the JWT header contains akidparameter ({"alg": "HS256", "kid": "key-id"}). - Test Path Traversal: Modify the
kidto a path traversal sequence like../../../../../../../dev/null. - Modify Payload: Update the JWT payload to escalate privileges or bypass authentication.
- Create Null Signing Key:
- In Burp Suite’s JWT Editor Keys, generate a new symmetric key for HS256.
- Set the key to a Base64-encoded null byte (
AA==) in the JWK.
- Sign Modified JWT:
- In Burp Repeater’s JSON Web Token tab, update the header’s
kidto the path traversal value. - Update the payload as needed.
- Sign the token with the null key, ensuring Don’t modify header is selected.
- In Burp Repeater’s JSON Web Token tab, update the header’s
- Send Request: Submit the modified JWT request to the server.
- Verify
- Mitigation
- Validate
kidstrictly — never allow user-controlled paths or queries - Use allowlists of valid
kidvalues with fixed file or key mappings
- Validate
- Exploiting IT
Algorithm confusion
-
How the Algorithm Confusion attack works
An application becomes vulnerable to an algorithm confusion attack when the developer uses the same public key to verify the JWT signature, whether the algorithm is symmetric or asymmetric.
Although it may seem unlikely, a developer can sometimes assume that the algorithm used will always be asymmetric, without explicitly checking.
This type of behaviour can be illustrated by the following code:
publicKey = <public-key-of-server>;token = request.getCookie("jwt");verify(token, publicKey); -
Exploiting
-
Obtain the server’s public key
Servers sometimes expose their public keys as JSON Web Key (JWK) objects via a standard endpoint mapped to
/jwks.jsonor/.well-known/jwks.jsonTools such as ‘rsa_sign2n’ can be used for this
docker build -t sign2ndocker run -it --rm sign2n /bin/bashpython3 jwt_forgery.py <first_jwt> <second_jwt> -
Modify your JWT
-
Sign the JWT using the public key https://gchq.github.io/CyberChef/#recipe=JWT_Sign(‘secret’,‘HS256’,‘%7B%7D’)&ieol=CRLF&oeol=CRLF
-
Mitigation: Never trust the “alg” field from the JWT itself.
Resource
PayloadsAllTheThings/JSON Web Token at master · swisskyrepo/PayloadsAllTheThings
The Ultimate Guide to JWT Vulnerabilities and Attacks (with Exploitation Examples)
JWT: Vulnerabilities, Attacks & Security Best Practices
JWT attacks | Web Security Academy
Challenges/Web - Server [Root Me : Hacking and Information Security learning platform]
Some information may be outdated




