June 12, 2026
JWT Attacks: Algorithm Confusion Vulnerability
Hi Hackers,
Mayank Kumar Prajapati
6 min read
I am back with another blog on an interesting vulnerability known as Algorithm Confusion/Key Confusion Vulnerability. We will dissect this vulnerability to make it easy to understand. Below are the topics that will cover in this blog.
- What is Algorithm Confusion Vulnerability?
- Common Endpoints to find out Public Key
- Performing Algorithm Confusion Attack with jwks.json
- What if you don't find jwks.json anywhere?
- Root Cause of this vulnerability
- Mitigation Approach
1. What is Algorithm Confusion Vulnerability?🤔
We would need to understand the normal flow of token exchange and token verification when it comes asymetric algorithms such as RS256 to get started. Below is the diagramatic representation of how token exchange along with verification takes place between client and server. Have a look on it and understand each and every step.
Step 1: User provides valid credentials to login into the application. Step 2: Application server issues the JWT token signed with RS256 algorithm which uses private key to sign the token and public key to verify it. Step 3: User call the post authenticated application endpoints/APIs with the help of token received in earlier step. Step 4: Server verifies the JWT token using the public key and provides the access to the user.
Algorithm confusion is a type of vulnerability associated with JWT token in which the attacker force the server to use different algorithm for token verification purpose. The trick here is that public key is usually available and intended to access to everyone. In this attack, attacker modifies the algorithm from RS256 to HS256 and then grabs the public key from the open source to use it to sign the JWT token. If the server accepts this modified token with HS256 algorithm in the alg parameter of JWT token then it is vulnerable to Algorithm Confusion Vulnerability.
2. Common Endpoints to look for Public Key📢
Below are some of the common endpoints that you can utilize to find out the public key.
/.well-known/jwks.json
/jwks.json
/keys
/api/keys
/api/v1/keys
/openid/connect/jwks.json/.well-known/jwks.json
/jwks.json
/keys
/api/keys
/api/v1/keys
/openid/connect/jwks.jsonSometimes the endpoints depends upon the identity providers (IdPs) and frameworks used in the application to handle the authentication part. If you are aware about or have this information handy then you can access the endpoints as per the framework/IdP used. e.g.
https://{tenant}.okta.com/oauth2/v1/keys
https://{tenant}.okta.com/oauth2/{authServerId}/v1/keys
https://{KEYCLOAK_HOSTNAME}/realms/{realm-name}/protocol/openid-connect/certs
https://{tenant}.auth0.com/.well-known/jwks.jsonhttps://{tenant}.okta.com/oauth2/v1/keys
https://{tenant}.okta.com/oauth2/{authServerId}/v1/keys
https://{KEYCLOAK_HOSTNAME}/realms/{realm-name}/protocol/openid-connect/certs
https://{tenant}.auth0.com/.well-known/jwks.jsonThe example of jwks.json endpoint is given given below.
{
"keys": [
{
"kty": "RSA",
"use": "sig",
"alg": "RS256",
"kid": "prod-rsa-key-2026",
"n": "u1...[Truncated long Base64URL-encoded modulus string]...7m3Q",
"e": "AQAB"
},
{
"kty": "EC",
"use": "sig",
"alg": "ES256",
"kid": "backup-ec-key-01",
"crv": "P-256",
"x": "f83OJ3D2xF1Bg8vub9tLe1gHMz8bZf47E1c97N18L2U",
"y": "x_da7W5o_S1SpvA_VzCeb5Ff367o_S1SpvA_VzCeb5F"
}
]
}{
"keys": [
{
"kty": "RSA",
"use": "sig",
"alg": "RS256",
"kid": "prod-rsa-key-2026",
"n": "u1...[Truncated long Base64URL-encoded modulus string]...7m3Q",
"e": "AQAB"
},
{
"kty": "EC",
"use": "sig",
"alg": "ES256",
"kid": "backup-ec-key-01",
"crv": "P-256",
"x": "f83OJ3D2xF1Bg8vub9tLe1gHMz8bZf47E1c97N18L2U",
"y": "x_da7W5o_S1SpvA_VzCeb5Ff367o_S1SpvA_VzCeb5F"
}
]
}3. Performing Algorithm Confusion Attack with jwks.json👨💻
We have used below PortSwigger lab to demonstrate the vulnerability.
Lab: JWT authentication bypass via algorithm confusion This lab uses a JWT-based mechanism for handling sessions. It uses a robust RSA key pair to sign and verify tokens…
3(i). Pre-requisites🔨
Login into the application with valid credentials. Analyze that the application uses JWT token post authentication. This JWT token is encrypted with RS256 algorithm that can be proved by looking at alg parameter after decoding the token. Since application server uses RS256 algorithm, we should try algorithm confusion attack here.
3(ii). Steps to be followed🏃
As we have seen, that we can get public key by calling specific endpoints such as jwks.json, its time to exploit algorithm confusion vulnerability. Lets get the public key by browsing this endpoint in browser. Please note that disclosed public key is itself not a vulnerability, it is intended to have public access on it.
We will use JWT Editor BurpSuite extension to convert the public key we found in the suitable format. We need .pem file. In JWT Editor extension try generating a new key by click on New RSA Key. Copy paste the value of the public key that we found on jwks.json endpoint. It is important to note that you copy the value of the keys array not the array itself. To copy the value start copying from{"kty"… Also you may sometimes get multiple keys in keys array, in this case copy that value which matches the kid value of your JWT token. Paste the value as shown in below figure and click on OK.
Notice that it creates the key, right click on it and then select Copy Public Key as PEM.
Paste the value copied in earlier step in Decoder tab of BurpSuite and encode it in Base64 format.
Copy the Base64 encoded value. In JWT Editor Extension, try generating a symmetric key by clicking on New Symmetric Key option. Click on Generate button and paste the copied value in k parameter.
Send any authenticated request to the repeater. Change the algorithm to HS256 and username to another user such as high privileged user as shown in the below screenshot.
Sign this token using the key symmetric key we created earlier.
Repeat the request and notice that we are getting 200 OK instead of 401. It means that the application trusts this modified token that proves the existence of algorithm confusion vulnerability in this application.
4. What if you don't find jwks.json anywhere?😢
When public key is not available at the endpoints mentioned in this blog, in this case also public key can be extracted out using a pair of valid JWTs. We can request two valid JWTs by login into the application in different browsers. In below repo, there is a utility called jwt_forgery.py that can be used for this purpose.
GitHub - silentsignal/rsa_sign2n: Deriving RSA public keys from message-signature pairs Deriving RSA public keys from message-signature pairs - silentsignal/rsa_sign2n
I have used below portswigger lab for demonstration purpose.
Lab: JWT authentication bypass via algorithm confusion with no exposed key This lab uses a JWT-based mechanism for handling sessions. It uses a robust RSA key pair to sign and verify tokens…
Get two valid JWT tokens by login in into the application. You can use different browsers for this purpose. Run the tool jwt_forgery.py as shown below.
git clone https://github.com/silentsignal/rsa_sign2n.git
cd rsa_sign2n/standalone
python jwt_forgery.py {TOKEN1} {TOKEN2}git clone https://github.com/silentsignal/rsa_sign2n.git
cd rsa_sign2n/standalone
python jwt_forgery.py {TOKEN1} {TOKEN2}
Lets copy the JWT tokens generated by this script one by one and checks which one works for you. In my case incorrect token redirects me the /login page whereas the correct token provides 200 OK as shown below.
Since the first token worked, we will rely on the first .pem file generated which was b4beb079fc5c6d82_65537_x509.pem according the tool output shown above in the screenshot. Lets base64 encode the content of this file.
Copy the base64 generated content and generate a symmetric key using JWT Editor extension by providing copied value in k parameter in the way we did earlier.
Change the endpoint to high privileged endpoint which was not currently acccesible with your user.
Modify the algorithm value from RS256 to HS256 and username to high privileged account. Finally sign this token using the symmetric key we generated using JWT Editor extension.
Notice that we can access the application as high privileged acccount as well that confirms the presence of algorithm confusion vulnerability.
5. Root Cause of this vulnerability👿
The problem arises when the developers doesn't explicitly specify which algorithm to use while verifying the token. If the token is signed with public key and the value of the alg parameter was kept to HS256 then verify() function relies on HS256 instead of RS256 to verify the token that results in bypassing authentication. Below is the example of vulnerable code that uses public key to verify the token.
publicKey = <public-key-of-server>;
token = request.getCookie("session");
verify(token, publicKey);publicKey = <public-key-of-server>;
token = request.getCookie("session");
verify(token, publicKey);6. Mitigation Approach🔨
The best recommendation to fix algorithm confusion vulnerability is to whitelist the algorithm. It can be done by hardcoding it as shown in the below code.
publicKey = <public-key-of-server>;
token = request.getCookie("session");
// SECURE: Enforce that only the expected asymmetric algorithm (e.g., RS256) is accepted
const options = { algorithms: ['RS256'] };
try {
const decoded = verify(token, publicKey, options);
// Token is valid and verified using RS256
} catch (error) {
// Handle invalid token (or algorithm mismatch)
}publicKey = <public-key-of-server>;
token = request.getCookie("session");
// SECURE: Enforce that only the expected asymmetric algorithm (e.g., RS256) is accepted
const options = { algorithms: ['RS256'] };
try {
const decoded = verify(token, publicKey, options);
// Token is valid and verified using RS256
} catch (error) {
// Handle invalid token (or algorithm mismatch)
}Hope you enjoyed reading🙂
LinkedIn: https://www.linkedin.com/in/mayank-kumar-prajapati/