Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Session is dead - Long live JWT @ RigaDevDays 2017

Session is dead - Long live JWT @ RigaDevDays 2017

In Software Development things are continuously changing.
Solutions that were completely fine just a moment ago, can prove to be a source of great pain now.
And one of those solutions that worked perfectly just last week, but isn't that perfect now is Session.

We all now that HTTP is a Stateless protocol, so the smart IT community figured out a way to bypass this limitation by introducing Sessions and Cookies.
But from Session-related attacks on the client-side, to problems with maintaining Session integrity on the server-side.
We found out that hacking protocols has its price.

So now it's time to take a different approach.
An approach more in line with the way today's Apps are implemented.
Enter JWT (JSON Web Token) - a Stateless solution to a Stateful problem.

This lecture will take a look at what JWT actually is and how it can be used as a replacement for Session.
It will also try to summarize what problems JWT solves (and what problems it creates) with regards to the old Session approach.
And finally, answer some of the common questions surrounding this new way of handling Users in our Apps.

Hrvoje Crnjak

May 16, 2017
Tweet

More Decks by Hrvoje Crnjak

Other Decks in Programming

Transcript

  1. Session is Dead
    Long live JWT
    Hrvoje Crnjak
    Software Developer @ Five
    @HrvojeCrnjak

    View Slide

  2. JWT = “jot” /dʒɒt/

    View Slide

  3. Session vs. JWT
    Reference vs. Data object
    Stateful vs. Stateless

    View Slide

  4. Debunked
    (JSON Web Token)
    NOT Authentication Protocol
    NOT Authorization Protocol

    View Slide

  5. Debunked
    (JSON Web Token)
    NOT Protocol
    Standard for representing data

    View Slide

  6. The catch is in how we use JWTs

    View Slide

  7. Client – Server communication
    Session ID + Cookie
    POST /authenticate
    username= &password=...
    Client
    Server
    HTTP 200 OK
    Set-Cookie: session=0B3...
    https://app.yourapp.com
    GET /api/user
    Cookie: session=0B3...
    HTTP 200 OK
    {name: foo }
    Find stored session
    based on Session ID
    Create session and
    store it on server-side

    View Slide

  8. POST /authenticate
    username= &password=...
    Client
    Server
    HTTP 200 OK
    {token: ...JWT }
    https://app.yourapp.com
    GET /api/user
    Authorization: Bearer ...JWT...
    HTTP 200 OK
    {name: foo }
    Client – Server communication
    JWT + Authorization header
    Validate token
    and extract data
    Create token with
    necessary User data
    (basic info, roles, etc.)

    View Slide

  9. Session vs. JWT analysis
    Session
    • Authentication
    • On the Server
    • Create Session
    • Store Session
    • Response
    • Session ID
    • Client storage in Cookie
    • Accessing Resource
    • Cookie header with Session ID
    • Find Session based on ID
    JWT
    • Authentication
    • On the Server
    • Create Token
    • DO NOT store Token
    • Response
    • Token
    • Client storage up to JS
    • Accessing resource
    • Authorization header with JWT
    • Read data from JWT itself

    View Slide

  10. View Slide

  11. • JSON Web Token
    • Open standard
    • IETF - RFC 7519
    • Proposed in May 2015

    View Slide

  12. • Standard for representing claims between parties
    • Transferred securely and in compact and URL-safe way
    • Compact and URL-safe
    • Base64 encoded with URL-safe alphabet
    • ( - , _ ) instead of ( + , / )
    • Claim
    • A piece of information about a subject (user)
    • Represented as name/value pair
    • Claim Name - always string
    • Claim Value - any JSON value

    View Slide

  13. • Claim names
    • Registered Claim names
    • Defined by the JWT standard
    • Public Claim names
    • Defined by 3rd parties and registered at IANA
    • Usually defined by standards that rely on JWT
    • example : OpenId Connect (given_name, family_name, nicnkname, …)
    • Private Claim names
    • Custom names defined by JWT users
    • Anyone creating and using JWTs in their App
    • All Claims are optional

    View Slide

  14. • Registered Claim names (claims)
    {
    }

    View Slide

  15. • Registered Claim names (claims)
    {
    jti : “JWT ID”
    }

    View Slide

  16. • Registered Claim names (claims)
    {
    jti : “JWT ID”,
    iss : “JWT Issuer”
    }

    View Slide

  17. • Registered Claim names (claims)
    {
    jti : “JWT ID”,
    iss : “JWT Issuer”,
    sub : “Subject of JWT”
    }

    View Slide

  18. • Registered Claim names (claims)
    {
    jti : “JWT ID”,
    iss : “JWT Issuer”,
    sub : “Subject of JWT”,
    aud : “Audience – intended recipients”
    }

    View Slide

  19. • Registered Claim names (claims)
    {
    jti : “JWT ID”,
    iss : “JWT Issuer”,
    sub : “Subject of JWT”,
    aud : “Audience – intended recipients”,
    iat : “Time at which JWT was issued”
    }
    Seconds Since
    the Epoch

    View Slide

  20. • Registered Claim names (claims)
    {
    jti : “JWT ID”,
    iss : “JWT Issuer”,
    sub : “Subject of JWT”,
    aud : “Audience – intended recipients”,
    iat : “Time at which JWT was issued”,
    nbf : “Time before which JWT must not be accepted”
    }

    View Slide

  21. • Registered Claim names (claims)
    {
    jti : “JWT ID”,
    iss : “JWT Issuer”,
    sub : “Subject of JWT”,
    aud : “Audience – intended recipients”,
    iat : “Time at which JWT was issued”,
    nbf : “Time before which JWT must not be accepted”,
    exp : “Time after which JWT must not be accepted”
    }

    View Slide

  22. • Example set of Claims
    {
    jti : “42987532342”,
    iss : “my-service”,
    exp : 1494580678,
    sub : “john1234”,
    name : “John Johnson”,
    email : “[email protected]”,
    roles : [“ADMIN”, “USER”]
    }

    View Slide

  23. • Example set of Claims
    {
    jti : “42987532342”,
    iss : “my-service”,
    exp : 1494580678,
    sub : “john1234”,
    name : “John Johnson”,
    email : “[email protected]”,
    roles : [“ADMIN”, “USER”]
    }

    View Slide

  24. • Example set of Claims
    {
    jti : “42987532342”,
    iss : “my-service”,
    exp : 1494580678,
    sub : “john1234”,
    name : “John Johnson”,
    email : “[email protected]”,
    roles : [“ADMIN”, “USER”]
    }

    View Slide

  25. • Example set of Claims
    {
    jti : “42987532342”,
    iss : “my-service”,
    exp : 1494580678,
    sub : “john1234”,
    name : “John Johnson”,
    email : “[email protected]”,
    roles : [“ADMIN”, “USER”]
    }

    View Slide

  26. • Securing JWT
    • Signed
    • Claims in “plain text”
    • Guaranteed token integrity
    • Defined through JWS (JSON Web Signature) standard
    • Encrypted
    • Claims encrypted
    • Guaranteed token integrity and data privacy
    • Defined through JWE (JSON Web Encryption) standard

    View Slide

  27. • Securing JWT
    • Signed
    • Claims in “plain text”
    • Guaranteed token integrity
    • Defined through JWS (JSON Web Signature) standard
    • Encrypted
    • Claims encrypted
    • Guaranteed token integrity and data privacy
    • Defined through JWE (JSON Web Encryption) standard

    View Slide

  28. • Signing JWT
    • A number of supported algorithms
    • Defined in JWA (JSON Web Algorithms) standard
    • Two algorithm groups
    • Symmetric key alg.
    • Same key for creating and validating signature
    • Offer integrity and authenticity
    • Asymmetric key alg.
    • Private key for creating signature, public for validating it
    • Offer integrity, authenticity and non-repudiation

    View Slide

  29. • Composing JWT

    View Slide

  30. • Composing JWT
    • 3 parts
    • Header
    • Holds info about algorithm used for signing
    • Payload
    • Holds claims
    • Signature
    • Base64 encoded and separated by “dot”
    Payload
    Header Signature

    View Slide

  31. • Composing JWT
    {
    sub : "1234567890",
    name : "John Doe",
    admin : true
    }
    Payload
    Header Signature
    Base64 encode data

    View Slide

  32. • Composing JWT
    {
    alg : “HS256",
    typ : “JWT“
    }
    Base64 encode data
    Payload
    Header Signature

    View Slide

  33. • Composing JWT
    SIGN (
    encoded_Header + “.” + encoded_Payload
    , secretKey
    )
    Base64 encode data
    Payload
    Header Signature

    View Slide

  34. • Composing JWT
    Payload
    Header Signature
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
    eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.
    TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

    View Slide

  35. View Slide

  36. JWT is Self-Contained

    View Slide

  37. Self-contained
    • All the relevant data is inside JWT
    • User information represented through claims
    • Data required to check its validity
    • Benefits
    • Client-side
    • User info can be read directly from token
    • User ID, name, email, roles, …
    • Server-side
    • Coming up next …
    Session ID
    JSESSIONID=8D4D409560B
    D4D0CCCA00105325115F3
    JWT
    {
    sub : "1234567890",
    name : "John Doe",
    role : “ADMIN”
    }

    View Slide

  38. JWT is Stateless

    View Slide

  39. Stateless
    • JWT is self-contained
    • No need for State
    • No data stored on Server-side
    GET /api/user
    Cookie: session=
    Session
    Storage
    GET /api/user
    Authorization: Bearer ...JWT...
    Session
    Storage

    View Slide

  40. JWT is Scalable

    View Slide

  41. Scalable
    • State is evil
    • When we use Session…
    POST /api/event
    Cookie: session=
    Session
    Storage
    Reverse
    Proxy
    GET /api/event/1
    Cookie: session=

    View Slide

  42. Scalable
    • State is evil
    • No State (Session) no problem!
    • No worries about
    • Accessibility
    • Availability
    • Synchronization
    POST /api/event
    Authorization: Bearer ...JWT...
    Session
    Storage
    Reverse
    Proxy
    GET /api/event/1
    Authorization: Bearer ...JWT...

    View Slide

  43. JWT is more flexible

    View Slide

  44. Flexible
    • Content of JWT completely configurable
    • Token creation and usage can be separated
    GET /api/event
    Authorization: Bearer ...JWT...
    HTTP 200 OK
    {name: foo }
    Auth.
    Provider
    Service
    Provider
    Client
    https://auth.outsorce.com
    https://your.app.com

    View Slide

  45. Flexible
    • Benefits
    • Outsource your auth. concerns
    • FB, Google, Amazon, Auth0, etc.
    • Disadvantages
    • Someone else can create valid tokens for your service
    • You need to trust the Auth. Provider
    • Setup
    • Register your App with Auth. Provider
    • Define claims needed in JWT
    • Agree on a shared key

    View Slide

  46. JWT is immune to CSRF attacks

    View Slide

  47. Immune to CSRF
    • “Session riding”
    • User tricked into making harmful requests
    • User already logged to that service
    • Relies on Session Cookie
    • No Session Cookie
    • No Problem

    View Slide

  48. Quick recap
    JWT Pros
    • Self-contained
    • Stateless
    • Scalable
    • More flexible
    • Auth. outsourcing
    • Immune to CSRF
    JWT Cons

    View Slide

  49. JWT is bigger

    View Slide

  50. Size
    • Smallest JWT larger than Session ID
    • Avg. Session ID + Cookie name = 45 Bytes
    • Header size constraints
    • HTTP defines none
    • But servers do
    • Tomcat – 8 KB
    • Jetty – 6 KB
    • For all headers combined!
    No. of Claims Size (Bytes)
    0 75
    1 125
    3 150
    5 225
    10 350
    15 550

    View Slide

  51. Unstandardized storage and
    transmission of JWTs

    View Slide

  52. Storage and transmission
    • With Cookies everything is handled automatically
    • Server instructs Browser to store Session ID
    • Browser automatically sends stored Session ID
    • With JWTs
    • Storage
    • Handled by client-side JS
    • Transmission
    • Handled by client-side JS

    View Slide

  53. JWT is more vulnerable to XSS
    attacks

    View Slide

  54. XSS problem
    • Cross-site scripting
    • Like “SQL injection” – but for client-side JS
    • Rogue JS
    • It can
    • Change the data displayed to the User
    • Make harmful requests to the Server
    • It can’t
    • Steal your Session ID (inside HttpOnly Cookie)
    • But it can steal JWT
    • Handled by client-side JS
    • Solution
    • Sanitize User inputs!

    View Slide

  55. Signed, not encrypted*

    View Slide

  56. Signed, not encrypted*
    • Common use-case
    • Signed JWTs
    • Readable on client-side
    • “Solution”
    • Use encrypted JWTs
    • Disadvantage
    • Client can’t read User info from JWT
    • Client needs to contact Server to get that info
    • Golden rules
    1) Don’t put anything too sensitive inside JWT
    2) Always use HTTPS

    View Slide

  57. Token revocation

    View Slide

  58. Token revocation
    • How to deny access to already logged User?
    • Friendly User
    • Logged out
    • Discontinued Account
    • Solution
    • Session
    • Session is invalidated server-side
    • JWT
    • Token is deleted client-side

    View Slide

  59. Token revocation
    • How to deny access to already logged User?
    • Harmful User
    • Hijacked Session ID or JWT
    • Banned
    • Solution
    • Session
    • Session is invalidated server-side
    • JWT
    • No explicit way of revoking already issued tokens
    • Only trade-offs

    View Slide

  60. Token revocation
    • “Revoking” JWT token
    • Keep a list of revoked JWTs
    • Disadvantage
    • Introducing state to server-side
    • Make JWTs short-lived
    • Disadvantage
    • User needs to login more frequently
    • Refresh tokens can be used to mitigate frequent login issue
    • Nuclear option
    • Change JWT signing key
    • Invalidate all previously issued tokens
    • Disadvantage
    • All users denied access

    View Slide

  61. Quick recap
    JWT Pros
    • Self-contained
    • Stateless
    • Scalable
    • More flexible
    • Auth. outsourcing
    • Immune to CSRF
    JWT Cons
    • Size
    • Storage and transmission
    • More vulnerable to XSS
    • Signed vs. encrypted
    • Token revocation

    View Slide

  62. Quick recap
    JWT Pros
    • Self-contained
    • Stateless
    • Scalable
    • More flexible
    • Auth. outsourcing
    • Immune to CSRF
    JWT Cons
    • Size
    • Storage and transmission
    • More vulnerable to XSS
    • Signed vs. encrypted
    • Token revocation

    View Slide

  63. Final considerations …

    View Slide

  64. Q & A
    With myself…

    View Slide

  65. FAQ #1
    What’s the relation between
    JWTs and OAuth2 ?

    View Slide

  66. #1 JWT vs. OAauth2
    • Solve different kinds of problems
    • JWT
    • Standard for representing and transferring data
    • OAuth2
    • Authorization framework
    • They’re complementary
    • Typical use case
    • JWTs as “vessels” for carrying data between different OAuth
    components
    • Defined through IETF standard

    View Slide

  67. FAQ #2
    You mentioned refresh tokens?
    What are they exactly?

    View Slide

  68. #2 Refresh tokens
    • Usually used together with short-lived access JWTs
    • Idea
    • When the User authenticates
    • Auth. Provider returns 2 tokens
    • Access token (short-lived)
    • Refresh token (long-lived)
    • Upon access token expiry
    • Send refresh token to Auth. provider to get new access token
    • Done automatically without User’s “knowledge”

    View Slide

  69. FAQ #3
    When would JWTs be a god fit?

    View Slide

  70. #3 A good fit
    • Up to you to make that decision 
    • You could consider…
    • Single page Apps
    • Server-side is just REST API
    • Outsource Authentication concerns
    • Smaller / non-critical Apps
    • Larger Apps
    • Improved User experience
    • Server-to-server communication
    • Between services inside your organization

    View Slide

  71. Thanks for your time!
    Q & A

    View Slide

  72. Spring Security + JWT
    example
    Github
    hcrnjak / spring-jwt-example

    View Slide