JWTs are trusted by millions of APIs worldwide: yet one small misconfiguration can turn a security feature into an attacker’s gateway
Press enter or click to view image in full size
In this blog, you will learn what JWT vulnerabilities are, how attackers exploit them in real-world APIs, and how to identify and prevent them. We will cover two powerful attack techniques step by step:
JWT vulnerabilities are usually not caused by the JWT standard itself, but by insecure implementation practices. Common mistakes include trusting the algorithm specified inside the token, using weak or hardcoded secrets, and failing to validate important claims such as expiration time and audience.
Because of these misconfigurations, attackers often do not need to break encryption to compromise authentication systems. Instead, they exploit weak validation logic and developer assumptions to forge or manipulate tokens and gain unauthorized access.
To demonstrate this vulnerability, I used crAPI (Completely Ridiculous API), a deliberately vulnerable API application designed for practicing API security testing.
Let’s first log in using valid credentials
Press enter or click to view image in full size
After authentication, the server provides a JWT token. As you can see in the screenshot
Press enter or click to view image in full size
The JWT token is sent with each request to verify the identity of the authenticated user. After logging in, I navigated to the dashboard and intercepted the request in Burp Suite. As shown in the request, the application uses bearer token authentication.
In APIs, authentication is commonly handled through bearer tokens instead of cookies. Unlike cookies, which the browser stores and sends automatically, bearer tokens must be explicitly attached to each request. JWTs include a signature that protects the token’s integrity. If any part of the token is modified, the signature becomes invalid, allowing the server to detect tampering.
Press enter or click to view image in full size
In a JSON Web Token (JWT), modifying the payload invalidates the original signature, so a new signature must be generated. In this attack, we manipulate the token and create a new signature to test whether the server accepts it.
The original token uses the RS256 algorithm, which relies on asymmetric cryptography using a public key and a private key. The public key is often exposed through the application, while the private key remains securely stored on the server. JWT also supports HS256, a symmetric algorithm that uses a single secret key for signing and verification.
In this attack, we change the algorithm from RS256 to HS256 and use the RSA public key as the signing key to forge a malicious token. If the server blindly trusts the algorithm specified inside the token, it may accept the forged token. To perform this attack, The RSA public key is commonly exposed through the application’s JWKS endpoint (e.g., /.well-known/jwks.json). If not available there, it can also be discovered through content discovery or directory brute-forcing
Press enter or click to view image in full size
Copy this key and go to Burp Suite JWT Editor
Press enter or click to view image in full size
What we found is not the actual key, but the “e” and “n” values, which can be used to reconstruct the RSA public key. In Burp Suite JWT Editor, click on “New RSA Key” and paste these values into the key section. Initially, the key may appear invalid because of formatting issues. The JWKS endpoint returns a JSON object with a ‘keys’ array containing one or more key objects. Since Burp Suite JWT Editor expects a single key object, remove the outer ‘keys’ wrapper and its surrounding brackets, keeping only the individual key object. Once the format is corrected, the key will be accepted successfully.
Press enter or click to view image in full size
we have values now we can create public key through this
Press enter or click to view image in full size
Click on the PEM, the public key is generated
Press enter or click to view image in full size
Press enter or click to view image in full size
Copy the generated public key and open the Decoder tab in Burp Suite. Paste the key into the input field, then use the Base64 encoding option on the right side to encode the key. Copy the Base64-encoded value and return to the JWT Editor.
Press enter or click to view image in full size
Click on “New Symmetric Key” and then click the “Generate” button. After the key is generated, replace the value of the “k” parameter with the Base64-encoded key you copied earlier.
Press enter or click to view image in full size
Press enter or click to view image in full size
The key is now generated and ready to be used for signing the token.
Press enter or click to view image in full size
Go back to the Proxy tab and send the dashboard request to Repeater. As shown in the request, the JSON Web Token (JWT) option is now visible and attached to the request.
Press enter or click to view image in full size
As shown in the JWT request, we can see which algorithm is being used, what type of data is included in the payload, and the signature attached at the end of the token.
Press enter or click to view image in full size
Suppose we change the user role from “user” to “admin.” Since modifying the payload invalidates the original signature, we must generate a new signature for the token.
Join Medium for free to get updates from this writer.
Click on the “Sign” button to open the signing dialog window. Scroll down and select the symmetric key that we created earlier. The original algorithm used by the token is RS256, which relies on asymmetric cryptography. We change the algorithm to HS256, which uses symmetric cryptography, and then click on “Update/Generate” for the “alg” parameter. The algorithm value changes from RS256 to HS256. Finally, click “OK” to generate the updated token.
Press enter or click to view image in full size
As we can see, the signature has changed and is now much shorter. The algorithm has been changed from RS256 to HS256, and the signature has been updated accordingly.
Press enter or click to view image in full size
Click on the Raw tab, then click Send. As we can see in the Response tab, the request is successfully accepted.
If it is not accepted, it will show an error such as “JWT is not accepted” or “Unauthorized.”
Press enter or click to view image in full size
In a None algorithm attack,the request is sent using the ‘none’ algorithm with an empty signature. The header and payload remain Base64URL encoded, but the server skips signature verification entirely, accepting the token without validating its integrity. Sometimes this vulnerability occurs when developers do not implement proper security controls.
If the server incorrectly processes the “none” algorithm, it may ignore the signature verification altogether.
Press enter or click to view image in full size
We send this request, and it is successfully accepted.
Press enter or click to view image in full size
Also, we can modify the payload in the decoded form on the right side. We enter another user’s email address and view the details of that user.
Press enter or click to view image in full size
iss, aud, exp, and nbf