Insecure JSON Web Tokens
Theory
Some web applications rely on JSON Web Tokens (JWTs) for stateless authentication and access control instead of stateful ones with traditional session cookies. Some implementations are insecure and allow attackers to bypass controls, impersonate users, or retrieve secrets.
Practice
Testers need to find if, and where, the tokens are used. A JWT is a base64 string of at least 100 characters, made of three parts (header, payload, signature) separated by dot, and usually located in Authorization
headers with the Bearer
keyword. See the the following example.
Once the tokens are found, testers need to assess their implementation's security by attempting some known attacks and flaws.
Sensitive data
JWTs are just base64 encoded data. They may contain sensitive unencrypted information.
Signature attack - None algorithm
Testers need to decode the token, change the algorithm to None
(or none
, NONE
, nOnE
) in the header, remove the signature, and send the modified token. Some applications are vulnerable to this attack since some support a None algorithm for signature.
This can be done in Python.
If the token is accepted by the web app, it means the payload can be altered.
Signature attack - RS256 to HS256
If the algorithm used to sign the payload is RS256, testers can try to use HS256 instead. Instead of signing the JWT payload with a private key, using HS256 will make the web app sign it with a public key that can sometimes be easily obtained.
The following Python code can be used to identify if the web application is vulnerable to this attack.
If the token is accepted by the web app, it means the payload can be altered.
The jwt library imported in the following Python code raises an exception when attempting to use an asymmetric key or x509 certificate as an HMAC secret. Testers need to install version 0.4.3 pip/pip3 install pyjwt==0.4.3
.
Signature attack - KID header path traversal
The structure of this ID is not specified and it can be any string value (case-sensitive).
Cracking the secret
When JWT uses HMAC-SHA256
/384
/512
algorithms to sign the payload, testers can try to find the secret if weak enough.
Recovering the public key
In certain scenarios, public keys can be recovered when knowing one (for algos ES256
, ES384
, ES512
) or two (for algos RS256
, RS384
, RS512
) tokens.
Resources
Last updated
Was this helpful?