As per jwt.io:
JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.
JWT (JSON Web Token) is widely used for authentication and authorization purposes. When a user enters their credential to sign in, the application verifies the credential, and if matched, issues a JWT to the user. Browser then sends the JWT to the server (usually through the
Authorization header or cookies) for accessing protected resources.
There are 3 parts of a JSON Web Token which are separated by dots (
Let's understand each of them one by one,
This section is then encoded using base64Url which results in
Mostly, there are two algorithms used in JWT: RS256 (uses the private key to sign the JWT and public key for verifying) and HS256 (uses a secret key to sign and verify).
exp are issued at time (when the JWT is issued) and expiration time (when the JWT will expire) respectively.
This section is then encoded using base64Url to form the second part of the JWT. This results in
This results in
So the final JWT would be:
You can decode a JWT using jwt.io:
Before proceeding with the common vulnerabilities present in JWT, we need a burp extension called "JSON Web Tokens". You can download it by navigating to the extender tab and searching for the name in the BApp Store.
none algorithm where any token would be considered valid if the signature is empty. For example, the token
eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJpYXQiOiIxNjk1MDIzODg3IiwiZXhwIjoiMTY5NTAyNTY4NyIsImVtYWlsIjoidHVoaW4uYm9zZUBidWdiYXNlLmluIiwiaXNBZG1pbiI6dHJ1ZX0. will be considered as valid. If you notice carefully, there is no signature part here and the header and body are just base64UrlEncoded. You can also try changing the algorithm to
hashcat -a 0 -m 16500 <JWT-Token> <Path-to-Wordlist>
We can use
rockyou.txt or any other popular wordlist for this.
HS256 (in the header) and use their public key to verify the token. You can get the certificate of the web server using the following command:
openssl s_client -connect example.com:443 2>&1 < /dev/null | sed -n '/-----BEGIN/,/-----END/p' > certificatechain.pem
openssl x509 -pubkey -in certificatechain.pem -noout > pubkey.pem
As you can imagine, the database must have a secret key corresponding to the id
68bf80e1-ecbb-4e36-a976-5eeb0d4d50fb. The application will fetch the secret key from the database and use it to verify the JWT token. Another example would be,
After receiving the JWT, the backend will fetch the key from the above URL and then use the key to sign/verify the token. Now since the KID can be controlled by the user, there can be multiple vulnerabilities:
It may possible that in the backend the application is passing the KID value directly into a command without proper sanitization:
Now, in this case, an attacker can simply achieve RCE by the following payload: We can also try directory traversal attack if the KID contains path of the secret key. In this case, we will use a publicly available file to verify the token.
3. If the KID contains the URL of the secret key like this:
We can try changing the URL to our controlled domain so that the secret key is fetched from our server to verify the JWT.
If the application allows only
RS256 algorithm, we can try to generate the public and private key by the following command:
ssh-keygen -t rsa -b 4096 -m PEM -f jwtRS256.key
openssl rsa -in jwtRS256.key -pubout -outform PEM -out jwtRS256.key.pub
How to Hunt These Vulnerabilities?
i. Look for an endpoint that returns some data about the user if the given JWT is correct, otherwise returns 401 or a similar response. Usually profile page is a good start.
ii. Manipulate JWT in the request and try each vulnerability (if applicable) one by one.
There are many more vulnerabilities related to JWT. We will discuss it in part 2 of this blog.
For automating most of the attacks, you can use jwt_tool. Check their
README.md for installation and usage instructions.
 Hacktricks: https://book.hacktricks.xyz/pentesting-web/hacking-jwt-json-web-tokens
 Payloads All The Things: https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/JSON%20Web%20Token
JWT.io by Auth0: https://jwt.io/introduction