Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Jwt == insecurity?

13,057 views

Published on

Slides for my recent talk at Ruxmon on the security of JSON Web Token. Covers patterns, CVE-2018-0114, example of issues in usage of JOSE libraries...

Published in: Internet

Jwt == insecurity?

  1. 1. JWT == insecurity? A journey in the insecurity of JSON web tokens… by Louis Nyffenegger @PentesterLab louis@pentesterlab.com
  2. 2. Introduction01 Agenda The JWT format (simplified)02 By Design03 Libraries04 Using Libraries05 Conclusion06 PentesterLab.com / @PentesterLab
  3. 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. 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. 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
  6. 6. THE JWT FORMAT
  7. 7. JavaScript Object Notation (JSON) PentesterLab.com / @PentesterLab Human readable format to store or transmit objects
  8. 8. The Compact JWS Format PentesterLab.com / @PentesterLab Header Payload Signature 3 parts in a JSON Web Token:
  9. 9. The Compact JWS Format PentesterLab.com / @PentesterLab Header Payload Signature Separated by a dot . .
  10. 10. The Compact JWS Format PentesterLab.com / @PentesterLab eyJ0eXAiOiJK V1QiLCJhbGci OiJIUzI1NiJ9 eyJsb2dpbi I6ImFkb WluIn0 FSfvCBAwypJ4abF6 jFLmR7JgZhkW674 Z8dIdAIRyt1E Separated by a dot . . eyJ = Base64('{"')
  11. 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. 12. The Compact JWS Format: Encoding PentesterLab.com / @PentesterLab Urlsafe base64 encoding without padding: *https://tools.ietf.org/html/rfc7515#appendix-C
  13. 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. 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. 15. The JWT Format: Algorithms PentesterLab.com / @PentesterLab Scenario: one client talking to multiple services
  16. 16. The JWT Format: Algorithms PentesterLab.com / @PentesterLab HS256 HS384 HS512 HMAC: All services need to know the secret
  17. 17. The JWT Format: Algorithms PentesterLab.com / @PentesterLab HS256 HS384 HS512 HMAC: if one service gets compromised
  18. 18. The JWT Format: Algorithms PentesterLab.com / @PentesterLab HS256 HS384 HS512 HMAC: the secret is compromised for all services
  19. 19. The JWT Format: Asymmetric PentesterLab.com / @PentesterLab RS256 RS384 RS512 ES256 ES384 ES512 PS256 PS384 PS512 Asymmetric: sharing the key Private Public
  20. 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. 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. 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. 23. The JWT Format: payload PentesterLab.com / @PentesterLab … The payload may contain literally anything: Base64({"user":"admin", "roles": ["adm","users"]}). . …
  24. 24. The JWT Format: payload PentesterLab.com / @PentesterLab The payload may contain registered claims: Base64({"user":"admin", "exp":12…, "iat":1234.. }). .… …
  25. 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. 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. 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. 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
  29. 29. By Design
  30. 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. 31. By design: verifying signature PentesterLab.com / @PentesterLab The attacker controls the algorithm used: Downgrade attacks, confusion attack Base64({ "alg": "HS256", "typ": "JWS"}) … . . …
  32. 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 • Profit
  33. 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. 34. By design: verifying signature PentesterLab.com / @PentesterLab Claims are optionals and not always supported* Always-valid tokens? * Check https://jwt.io/
  35. 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. 36. By design: The None algorithm PentesterLab.com / @PentesterLab JWT RFC contains a None algorithm No integrity! Basically an unsigned token…
  37. 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 • Profit
  38. 38. Libraries
  39. 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. 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. 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
  42. 42. Libraries: Go-JOSE version <= 1.0.5 PentesterLab.com / @PentesterLab Non-compact/full format for JWS:
  43. 43. Libraries: Go-JOSE version <= 1.0.5 PentesterLab.com / @PentesterLab From: https://rwc.iacr.org/2017/Slides/nguyen.quan.pdf The issue:
  44. 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. 45. Libraries: Go-JOSE version <= 1.0.5 PentesterLab.com / @PentesterLab If the application trusts the protected*: * you cannot change the payload
  46. 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 • Profit
  47. 47. Using libraries
  48. 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 offline) Integrity bypass!
  49. 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. 50. Using Libraries: decode vs verify PentesterLab.com / @PentesterLab Exploitation: • Get a token • Decode and tamper with the header or payload • Profit
  51. 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?
  52. 52. Conclusion
  53. 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. 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. 55. Any questions? FOR YOUR TIME THANKS! louis@pentesterlab.com / PentesterLab.com / @PentesterLab

×