3. About Me
PentesterLab.com / @PentesterLab
Security Engineer:
PentesterLab:
Pentester/Code Reviewer/Security consultant/Security architect
Platform to learn web security/penetration testing
100% Hands-on
Available for individuals (free and PRO) and enterprises
Run a website to help people learn security
4. JOSE/JWE/JWS/JWT
PentesterLab.com / @PentesterLab
โข JOSE:
โข Javascript Object Signing and Encryption
โข Also the name of the working group
โข JWT: JSON Web Token == โjotโ Token
โข JWE: JSON Web Encryption
โข JWS: JSON Web Signature
โข JWK: JSON Web Key
โข JWA: JSON Web Algorithm
5. Who uses JWT
PentesterLab.com / @PentesterLab
โข A lot of people for OAuth
โข A lot of people for sessions
โข A lot of people to manage trust
โข A lot of people for password reset
โข A lot of people who care about being stateless
and multi-datacenter architecture
7. JavaScript Object Notation (JSON)
PentesterLab.com / @PentesterLab
Human readable format to store or transmit objects
8. The Compact JWS Format
PentesterLab.com / @PentesterLab
Header Payload Signature
3 parts in a JSON Web Token:
9. The Compact JWS Format
PentesterLab.com / @PentesterLab
Header Payload Signature
Separated by a dot
. .
10. The Compact JWS Format
PentesterLab.com / @PentesterLab
eyJ0eXAiOiJK
V1QiLCJhbGci
OiJIUzI1NiJ9
eyJsb2dpbi
I6ImFkb
WluIn0
FSfvCBAwypJ4abF6
jFLmR7JgZhkW674
Z8dIdAIRyt1E
Separated by a dot
. .
eyJ = Base64('{"')
11. The Compact JWS Format
PentesterLab.com / @PentesterLab
Base64({โฆ}) Base64({โฆ}) Base64(โฆ)
Header and Payload are base64* encoded JSON
. .
* urlsafe base64 encoding without padding
The signature is also base64 encoded
12. The Compact JWS Format: Encoding
PentesterLab.com / @PentesterLab
Urlsafe base64 encoding without padding:
*https://tools.ietf.org/html/rfc7515#appendix-C
13. The JWT Format: header
PentesterLab.com / @PentesterLab
Base64({"alg": "HS256",
"typ": "JWS"})
The header contains an algorithm โalgโ attribute:
In this example HMAC with SHA256 was used
To tell how the token was signed.
โฆ
. . โฆ
14. The JWT Format: Algorithms
PentesterLab.com / @PentesterLab
A lot of different algorithms are supported*:
None
* https://jwt.io/ covers most
HS256
HS384
HS512
RS256
RS384
RS512
ES256
ES384
ES512
PS256
PS384
PS512
15. The JWT Format: Algorithms
PentesterLab.com / @PentesterLab
Scenario: one client talking to multiple services
16. The JWT Format: Algorithms
PentesterLab.com / @PentesterLab
HS256
HS384
HS512
HMAC: All services need to know the secret
17. The JWT Format: Algorithms
PentesterLab.com / @PentesterLab
HS256
HS384
HS512
HMAC: if one service gets compromised
18. The JWT Format: Algorithms
PentesterLab.com / @PentesterLab
HS256
HS384
HS512
HMAC: the secret is compromised for all services
19. The JWT Format: Asymmetric
PentesterLab.com / @PentesterLab
RS256
RS384
RS512
ES256
ES384
ES512
PS256
PS384
PS512
Asymmetric: sharing the key
Private
Public
20. The JWT Format: Asymmetric
PentesterLab.com / @PentesterLab
RS256
RS384
RS512
ES256
ES384
ES512
PS256
PS384
PS512
Asymmetric: Only trusted services get the
private key
Private
Public
21. The JWT Format: Asymmetric
PentesterLab.com / @PentesterLab
RS256
RS384
RS512
ES256
ES384
ES512
PS256
PS384
PS512
Asymmetric: If one service gets compromisedโฆ
Private
Public
22. The JWT Format: Asymmetric
PentesterLab.com / @PentesterLab
RS256
RS384
RS512
ES256
ES384
ES512
PS256
PS384
PS512
Asymmetric: Even in the browser!
Private
Public
23. The JWT Format: payload
PentesterLab.com / @PentesterLab
โฆ
The payload may contain literally anything:
Base64({"user":"admin",
"roles": ["adm","users"]}). . โฆ
24. The JWT Format: payload
PentesterLab.com / @PentesterLab
The payload may contain registered claims:
Base64({"user":"admin",
"exp":12โฆ, "iat":1234.. }). .โฆ โฆ
25. The JWT Format: payload
PentesterLab.com / @PentesterLab
The payload may contain registered claims:
โข โissโ: issuer
โข โsubโ: subject
โข โaudโ: audience
โข โjtiโ: claim id
โข โexpโ: expiration time
โข โnbfโ: not before
โข โiatโ: issued at*
* useful for async processing
26. The JWT Format: creating a token
PentesterLab.com / @PentesterLab
โข Create the JSON header and base64 encode it
โข Create the JSON payload and base64 encode it
โข Concatenate with a dot the (encoded) header
and payload
โข Sign the result (header+.+payload)
โข Base64 encode the signature
โข Append a dot then the signature
27. The JWT Format: verifying a token
PentesterLab.com / @PentesterLab
โข Split the token in three parts based on the dots
โข Base64 decode each part
โข Parse the JSON for the header and payload
โข Retrieve the algorithm from the header
โข Verify the signature based on the algorithm
โข Verify the claims
28. Keep in mind
PentesterLab.com / @PentesterLab
โข Multiple systems can issue tokens
โข A token can be used by multiple systems
โข All these systems can use different libraries
30. By design: verifying signature
PentesterLab.com / @PentesterLab
Base64({ "alg": "HS256",
"typ": "JWS"})
You need to base64 decode and parse
JSON to verify the signature:
Larger attack surface
JSON.load vs JSON.parse, Base64 decoding
โฆ
. . โฆ
31. By design: verifying signature
PentesterLab.com / @PentesterLab
The attacker controls the algorithm used:
Downgrade attacks, confusion attack
Base64({ "alg": "HS256",
"typ": "JWS"})
โฆ
. . โฆ
32. By design: Confusion attack
PentesterLab.com / @PentesterLab
Exploitation:
โข Get a token signed with RSA (you only have
access to the public key)
โข Decode the header and change the algorithm
from RSA โRS256โ to HMAC โHS256โ
โข Tamper with the payload
โข Sign the token with the public RSA key
โข Pro๏ฌt
33. By design: verifying signature
PentesterLab.com / @PentesterLab
โฆ
Claims are optionals and not always supported*:
Always-valid tokens?
Base64({"user":"admin",
"exp":12โฆ, "iat":1234.. }). . โฆ
* Check https://jwt.io/
34. By design: verifying signature
PentesterLab.com / @PentesterLab
Claims are optionals
and not always
supported*
Always-valid tokens?
* Check https://jwt.io/
35. By design: verifying signature
PentesterLab.com / @PentesterLab
Signed data: you cannot (easily) manage quick-
revocation*:
The claim โjtiโ and a cache can be used to limit
the impact of this
No quick-revocation! Replay
* Unless you rotate the key or manage a server-side cache
36. By design: The None algorithm
PentesterLab.com / @PentesterLab
JWT RFC contains a None algorithm
No integrity!
Basically an unsigned tokenโฆ
37. By design: The None algorithm
PentesterLab.com / @PentesterLab
Exploitation:
โข Get a token
โข Decode the header and change the algorithm to
โNoneโ or โnoneโ
โข Decode and tamper with the payload
โข Keep or remove the signature
โข Pro๏ฌt
39. Libraries: CVE-2018-0114
PentesterLab.com / @PentesterLab
JWS allows you to add a โjwkโ attribute (JSON Web
Key) to the header to tell the receiver what key was
used to sign the token:
40. Libraries: CVE-2018-0114
PentesterLab.com / @PentesterLab
โข Vulnerability in Cisco Node Jose
โข Node-Jose uses the embedded โjwkโ key to check
the signature
Integrity bypass!
41. Libraries: CVE-2018-0114 - Exploitation
PentesterLab.com / @PentesterLab
Exploitation:
โข Get a token
โข Decode and tamper with the payload
โข Generate a RSA key
โข Add โn" & โeโ to the header and use
RS256
โข Sign the token with your RSA key
43. Libraries: Go-JOSE version <= 1.0.5
PentesterLab.com / @PentesterLab
From: https://rwc.iacr.org/2017/Slides/nguyen.quan.pdf
The issue:
44. Libraries: Go-JOSE version <= 1.0.5
PentesterLab.com / @PentesterLab
From: https://rwc.iacr.org/2017/Slides/nguyen.quan.pdf
The issue:
Integrity of the protected bypass!
45. Libraries: Go-JOSE version <= 1.0.5
PentesterLab.com / @PentesterLab
If the application trusts the protected*:
* you cannot change the payload
46. Libraries: Go-JOSE version <= 1.0.5 - Exploitation
PentesterLab.com / @PentesterLab
Exploitation:
โข Get a token (compact or full)
โข Modify it to use the full format
โข Add your malicious protected
โข Pro๏ฌt
48. Using Libraries: weak secret
PentesterLab.com / @PentesterLab
Some developers use weak secrets.
Reminder: you only need one token to brute force
the secret (completely of๏ฌine)
Integrity bypass!
49. Using Libraries: decode vs verify
PentesterLab.com / @PentesterLab
A lot of libraries have two functions/methods:
โข decode <- donโt use this one
โข verify
Integrity bypass!
50. Using Libraries: decode vs verify
PentesterLab.com / @PentesterLab
Exploitation:
โข Get a token
โข Decode and tamper with the header or payload
โข Pro๏ฌt
51. Using Libraries: not using exp or iat
PentesterLab.com / @PentesterLab
In many libraries you need to opt-in to use โexpโ or
โiatโ
Always-valid tokens?
53. Recommendations
PentesterLab.com / @PentesterLab
โ Use strong keys and secrets
โ Review the libraries you pick (KISS library)
โ Make sure you check the signature
โ Make sure your tokens expire
โ Enforce the algorithm
54. Conclusion
PentesterLab.com / @PentesterLab
โข JWT are complex and kind of insecure by design
โข JWT libraries introduce very interesting bugs
โข Make sure you test for those if you pentest or do
bug bounties
55. Any questions?
FOR YOUR TIME
THANKS!
louis@pentesterlab.com / PentesterLab.com / @PentesterLab