News for hackers. Stuff that matters.
Re:Don't use JSON web tokens for sessions by merb on Monday June 13, 2016 @05:22PM (#11897774)

    You cannot invalidate JWT tokens
This is simple not true. You ALWAYS will sign your tokens with a well known secret, you could eventually even add some salt from a database to it.

    They are less secure
Compared to what? Actually JWT will have the same secureness like Bearer Tokens or Cookies, wherever you store it, its not `less` secure. Horrible article points here.

    They are less secure
They take the same amount of storage than signed cookies, wuhu I use JWT so often and I NEVER exceeded the cookie limit, but I wouldn't store them there anyway.

JWT is as secure as any other solution and this article proves it since he isn't well informed, he just throws a bunch of stuff out and tries to be "an expert". Btw. every other solution is really dangerous as well, especially Cookies could be a total mess of security problems. The same could actually happen with Bearer Tokens.

My toughts are use the thing your most happy with and the thing you understand and the thing you can implement with code that is totally clear and especially code that is really really easy to understand. And actually JWT will mostly win this battle.

I've seen a lot of people just using Session Cookies from their Framework, but eventually have no idea about their risks, they have lots of CSRF all over the place, or using a too small ID or eventually the ID is not really random. Eventually this could happen with JWT too, tough. As seen by this guy, that he generates the JWT without any well known secure string. that could be changed.

Re:Don't use JSON web tokens for sessions by lynndylanhurley on Monday June 13, 2016 @06:08PM (#11898131)

    You cannot invalidate JWT tokens
        

    This is simple not true. You ALWAYS will sign your tokens with a well known secret, you could eventually even add some salt from a database to it.
I think one of the benefits of some (most?) JWT implementations is that it doesn't hit the database on every request - the token is only validated against a global secret.

So you can't invalidate a single user's session without invalidating all users' sessions.

Re:Don't use JSON web tokens for sessions by low_key on Monday June 13, 2016 @07:35PM (#11898648)
I keep a counter in the JWT to at least mostly get around this issue. When processing a request, the counter is checked for the user, which isn't a big deal since all of the requests already require looking up the user. A counter increment invalidates all of that user's existing tokens.

If a user changes their password, their roles change, etc, then the counter gets incremented so all tokens issued up to that point won't be valid anymore.

Re:Don't use JSON web tokens for sessions by ForHackernews on Monday June 13, 2016 @11:33PM (#11899566)
Can you explain this a little bit more? You keep a counter on the user object in the DB? What is the JWT buying you if you still have to hit the DB on every request?
Re:Don't use JSON web tokens for sessions by mstade on Tuesday June 14, 2016 @08:59AM (#11901705)
Presumably you can keep counters like these on the server edges, and just push new values out to servers whenever things change, as opposed to query a DB every time. This wouldn't invalidate individual tokens however, but all tokens that have that counter value. It'd also mean there's a window where tokens can still be used while servers are being updated with the new value(s).

These are just some random and half-baked thoughts, I have no idea what OP does, but there are options to limit hitting backing DBs anyway.

Re:Don't use JSON web tokens for sessions by snikch on Monday June 13, 2016 @10:57PM (#11899458)
Yep ^ This is what I often do too. Simple, but effective.
Re:Don't use JSON web tokens for sessions by ekryski on Saturday June 18, 2016 @01:55PM (#11929772)
That's pretty smart. Effectively versioning your issued tokens. Way easier than maintaining a blacklist.
Re:Don't use JSON web tokens for sessions by njknsdf on Tuesday June 14, 2016 @09:57AM (#11902033)
You can store the user info in the JWT so you don't need to hit the database to get user info every time. I usually just store an id in each issued token and store/remove it from redis or memory as needed for invalidating it.
Re:Don't use JSON web tokens for sessions by ekryski on Saturday June 18, 2016 @01:54PM (#11929771)
You have to be careful that you are not leaking sensitive info though, as the JWT payload is meant to be visible on the client as well.
Re:Don't use JSON web tokens for sessions by mcherm on Monday June 13, 2016 @09:22PM (#11899119)
Yes you can. The system I built uses a revocation list (propagated to all servers in the cluster) to invalidate the session.

Just as if you were storing state on the server, it still requires a means of propagating the user's state to every server. But we only need to propagate a single ID once per session (at logout) instead of propagating all the session data to all the servers on every request.

Re:Don't use JSON web tokens for sessions by ademarre on Tuesday June 14, 2016 @12:48AM (#11899847)
To revoke with a revocation list, you need to know the ID of the token being revoked. That only works if (a) the token is present at the event that triggered the revocation, or (b) you are tracking all tokens, in which case there's probably not much point to using JWTs at all.

Another approach is what I call the "subject epoch" pattern. The subject of a token (the "sub" JWT claim) is often something like a user ID. When an event occurs that requires all tokens for a given subject to be revoked, save that time stamp as the subject's "epoch". When processing JWTs, those issued before the subject's epoch must be considered invalid.

Re:Don't use JSON web tokens for sessions by sb8244 on Monday June 13, 2016 @09:36PM (#11899166)
Do you ever worry that, in the case of failure or some other event, your revocation list could be lost and allow old hacked sessions to be used?

Is there a way around this? I like the idea of a revocation list, but this seems to be a pretty big concern.

Re:Don't use JSON web tokens for sessions by mcherm on Thursday June 16, 2016 @12:15PM (#11917091)
Not particularly. There are other layers of security here - the sessions expire (so there's a limited window to exploit each one), the sessions are always transmitted via SSL (so you pretty much have to have an exploit on the customer's system to get one), and the sessions are restricted to one customer (so you only have an attack against the customer whose system you have an exploit on).

If we used a different approach, then the same error (losing the data that's being synched) would result in losing all of the customer sessions.

Re:Don't use JSON web tokens for sessions by merb on Tuesday June 14, 2016 @03:02AM (#11900283)
The same problem occurs on every other method. i.e. Bearer/Cookies. As already said the most vulnerabilities applies to all methods. But people are just too blind to see that.
Re:Don't use JSON web tokens for sessions by RhodesianHunter on Monday June 13, 2016 @10:07PM (#11899287)
"old hacked sessions to be used"

JWTs generally contain an expiration timestamp.

Re:Don't use JSON web tokens for sessions by hueving on Tuesday June 14, 2016 @02:06AM (#11900107)
revocation list only needs to contain tokens that haven't expired. If there is an 'event' that causes this info to be lost, then expire everything by changing the global secret.
Re:Don't use JSON web tokens for sessions by brndn on Monday June 13, 2016 @09:34PM (#11899160)
Out of curiosity, how are you propagating the IDs to other systems in the cluster? I am building something which could benefit from pushing config data across a cluster.
Re:Don't use JSON web tokens for sessions by sk5t on Monday June 13, 2016 @11:12PM (#11899502)
In most cases it shouldn't matter; revocation lists ought to be trimmed to the lifetime of the issued tokens--when they are used at all, revoking a JWT rather than just letting it expire is likely not extremely common--so you could stuff them anywhere at all that is convenient to your other technology selections.
Re:Don't use JSON web tokens for sessions by centrinoblue on Tuesday June 14, 2016 @02:10AM (#11900116)
it's my understanding something like Redis is good for cross cluster im-memory persistence/reference
Re:Don't use JSON web tokens for sessions by seangrogg on Monday June 13, 2016 @08:02PM (#11898787)
I hit the database on requests - I keep their identity in the JWT but not their permissions. And if they're hitting a protected route (the only time their identity is necessary anyways) you best be sure I'm checking their canonical permissions.
Re:Don't use JSON web tokens for sessions by cortesoft on Monday June 13, 2016 @08:19PM (#11898866)
You might be, but many people use signed cookie sessions in order to avoid having to check the DB.
Re:Don't use JSON web tokens for sessions by Johnie on Monday June 13, 2016 @06:19PM (#11898207)
Can't you maintain session state in a Redis daemon and invalidate it there? Or are you talking about stateless JWT?
Re:Don't use JSON web tokens for sessions by DelaneyM on Monday June 13, 2016 @07:06PM (#11898491)
You include the time created in the object before signing, and invalidate based on that as a timeout.
Re:Don't use JSON web tokens for sessions by dandelany on Monday June 13, 2016 @07:23PM (#11898583)
Sure, but that's expiration, not invalidation, ie. we're talking about the ability to declare "this particular token is invalid now".

Incidentally, this limitation isn't too surprising to me... Is there any possible token-based authentication scheme that is both stateless (ie. no round trip to the database on every call) AND invalidate-able? Seems like any form of invalidation would require storing the "is valid" state somewhere else...

Re:Don't use JSON web tokens for sessions by DelaneyM on Monday June 13, 2016 @07:52PM (#11898733)
> Is there any possible token-based authentication scheme that is both stateless (ie. no round trip to the database on every call) AND invalidate-able?

I suspect this is provably impossible.

There are all sorts of things you can do at the protocol/platform level if you have a shared secret, but with only the constraints of an open authentication scheme you lack the tools to do this.

Re:Don't use JSON web tokens for sessions by gcommer on Monday June 13, 2016 @09:22PM (#11899118)
If you're willing to delve into the fun world of CRLs you can sorta do it. This isn't truly stateless of course, but for some design constraints it could be "practically" stateless since you're eliminating auth server round trips, which is probably why you were aiming for statelessness in the first place.

CRLs of course introduce lots of replication complexity and timing bounds to consider, and you probably want to pair them with short lived tokens to keep the CRL size manageable. (and then delve into refresh tokens)

As the OP points at, you most likely don't need any of this.

Re:Don't use JSON web tokens for sessions by merb on Tuesday June 14, 2016 @04:29AM (#11900605)
Eventually JWT has very little Roundtrips.

Our current Implementation is:

- Really short lived JWT of 1 minute - If the JWT is invalid and the user didn't do a request in the last minute it does query the database for a session token (we use session tokens and jwt). if the Token is inside the database/redis/ehcache/whatever the user gets still a new JWT token.

Actually we did that since we needed a "sane" way of revoking tokens fast but still keep the user logged in until the browser is closed.

We don't have a mobile client (yet) but I guess we try to do something like that, too. just not with a session. This works really well and mostly our users won't hang around for more than a minute and when they do its not a problem to have a single backend call.

Re:Don't use JSON web tokens for sessions by seangrogg on Monday June 13, 2016 @08:07PM (#11898803)
> stateless (ie. no round trip to the database on every call)

AFAIK, Stateless is about independent request/response and not needing a server to retain session information through the course of multiple requests. It has nothing to do with whether or not you're checking a database to cross-reference credentials - and I wouldn't keep anything more than an ID/name in a JWT... ever.

https://en.wikipedia.org/wiki/Stateless_protocol

Re:Don't use JSON web tokens for sessions by sk5t on Monday June 13, 2016 @11:55PM (#11899653)
JWT is good for much more than an ID+name; it's sensible to allow your partially-trusted token issuers to vouch for a _limited_ set of user roles and the like. Just the same way you probably wouldn't allow the @acme.com security authority to vouch for @example.com principals in a multi-tenant system... in ye olde SAML lingo this is called "claim filtering / transform / passthrough."

Practically speaking, we use a bit of metadata (jsonb documents in pgsql, mostly) for each JWT-issuing party, which describes how to validate principals, how to map incoming claims to "our" claims (e.g., "by what name does sts.acme.com call a 'role'? is sts.acme.com allowed to vouch for the 'admin' role?) in addition to the more central things like shared secrets, certificates, etc. This kind of partial trust is how claims auth is supposed to work, and avoids any unnecessary provisioning/syncing of user details.

Re:Don't use JSON web tokens for sessions by zeveb on Tuesday June 14, 2016 @10:55AM (#11902363)
> Is there any possible token-based authentication scheme that is both stateless (ie. no round trip to the database on every call) AND invalidate-able?

SPKI (RFC 2692/2693) solved this in 1999, with its timed CRLs. Exactly one CRL is valid for any given period of time: when a token (= certificate) is received, it is invalid if it is referenced in the CRL, and valid otherwise.

Re:Don't use JSON web tokens for sessions by numbsafari on Monday June 13, 2016 @05:40PM (#11897932)
Your first point is mostly dead on. I see a number of people stating that you cannot revoke a token, and it's simply not true.

The approach I use is to replace the shared session store (which is large, grows linearly with your user base, and hard to sync across clusters if you need that) with a shared revocation list.

The revocation list is small, easy to check, only contains IDs and a TTL, much less cumbersome to replicate... And is functionally equivalent.

If you have already gone the route of using a token for your session, it's really easy to implement and scales much better than a massive in memory store.

Re:Don't use JSON web tokens for sessions by pbz on Monday June 13, 2016 @07:31PM (#11898624)
The point of using a stateless token is that you don't have to hit a central server / service to verify each token. If you need to do that in order to check for revoked tokens (for each request) then that defeats the purpose. At that point you may as well just check the original token / key for validity.

The difference in speed between checking for a token in the big pool (all tokens) vs the small pool (revoked tokens) should be a lot smaller than the round trip to token server (i.e. network cost).

Also, you should be able to easily store millions of tokens on a single server (something like Redis). Do you really have a site that has multiple millions of people logged in?

Re:Don't use JSON web tokens for sessions by numbsafari on Monday June 13, 2016 @08:18PM (#11898860)
Sorry if that wasn't clear, but I absolutely agree you should use a distributed revocation list. As each request comes in, you need to check the list. But you do need to check the list, and you do need to distribute it widely.

Depending on your situation, managing a revocation list in memory at each edge node might be feasible, reducing the overhead of a network call to a per-cluster store, which is another advantage of using a short revocation list instead of a large session store that can't feasibly be shared like that.

(Edit: looking back at my comment, I shouldn't have said a "shared" revocation list, but a distributed one. Whoops!)

Re:Don't use JSON web tokens for sessions by merb on Monday June 13, 2016 @05:44PM (#11897958)
actually I often see stating that you should rely on a 3rd party authentication library since its mostly well known and well tested. While I would agree here I know that mostly the library will be your weak point since you have no idea how its implemented or whenever a new version comes around if it maybe has a security issue or if you keep your version if your vulnerable to something.

Actually most people should take their authentication mechanism as something really really important and not just rely on something. It's really important that your authentication/authorization stuff works and is hardened, not just for you, also for your users. I know that auth could be really hard, especially when the language of your choice contains some bugs, but its a nogo to just use something when it is that important. I don't mean that you can't use a library, but if you do please double check the code twice on each version.

Re:Don't use JSON web tokens for sessions by niteshade on Tuesday June 14, 2016 @04:56PM (#11905244)
I actually think your advice is more harmful than helpful - web developers are not renowned for writing secure software. This is a very good case of finding a good, well-tested and vetted library that does this. Not sure what options exist, but I would be highly surprised if there weren't any already.
Re:Don't use JSON web tokens for sessions by necubi on Monday June 13, 2016 @08:20PM (#11898867)
There are two common mechanisms for invalidating tokens:

* Store the invalidated tokens in some fast store, in memory store and check that before accepting tokens.

* Have auth tokens be very short lived (e.g., 1 minute) and require the use of a "refresh token" to get a new auth token when it's expired. This is the mechanism used by OAuth 2 (which strangely is never mentioned in the article). The refresh tokens should be random strings stored in a db, and they can be simply deleted on invalidation.

Re:Don't use JSON web tokens for sessions by zeckalpha on Monday June 13, 2016 @09:45PM (#11899199)
The second one is recommended by the article. They are differentiating between session and auth tokens, however.
Re:Don't use JSON web tokens for sessions by NathanKP on Monday June 13, 2016 @05:41PM (#11897940)

   You ALWAYS will sign your tokens with a well known secret, you could eventually even add some salt from a database to it.
Exactly. Each JWT I generate has a salt inside which I store in the DB, and ideally the salt has accompanying data such as the datetime the JWT was generated, the IP address that generated it, etc. Now you can provide an interface that lists "sessions" and allows the invalidation of logged in sessions by deleting the salt from the DB, rendering the JWT invalid.
Re:Don't use JSON web tokens for sessions by rahkiin on Monday June 13, 2016 @05:53PM (#11898032)
Using IP addresses for session (in)validation is pretty useless now that everybody has a mobile device that moves between networks (WiFi at home, WiFi at work, 3G/4G). If you use the website while walking from WiFi to 4G you would lose session.
Re:Don't use JSON web tokens for sessions by NathanKP on Monday June 13, 2016 @07:16PM (#11898547)
This is for the use case of: "Something weird happened on my account, so I check sessions and see that someone used my account from across the country. So I log out other sessions."
Re:Don't use JSON web tokens for sessions by mwpmaybe on Monday June 13, 2016 @05:48PM (#11897981)
I asked this question below, but how do you use the payload to select the correct salt from the database in order to verify the signature before verifying the signature and confirming that the payload is valid?
Re:Don't use JSON web tokens for sessions by merb on Monday June 13, 2016 @05:55PM (#11898043)
one way would be:

    - generate the salt
    - generate the jwt
    - use the header base64 string as the key for your database
    - store the salt with the header base64 as the key in your database
maybe?

just one idea, basically when you are > 100.000 users you barely invalidate a single token. mostly you would kill of your secret which will invalidate any token anyway. but there are numerous ways of doing so.

Edit:

to the poster after me:

actually we never needed to logout a single user. but actually our authorization is not stored in our JWT so if we want to kill a user off, we could just remove any rights from him so he gets a site where he needs to either logout or refresh (which will show him the same site again).

Re:Don't use JSON web tokens for sessions by mwpmaybe on Monday June 13, 2016 @05:57PM (#11898057)
Invalidating the site secret is my go-to strategy right now, but I have wondered how to sign out a single user across all their logged-in devices. Anyway, this idea is interesting and would be pretty straightforward to implement. Thanks!
Re:Don't use JSON web tokens for sessions by numbsafari on Monday June 13, 2016 @08:27PM (#11898905)
The point is to avoid all the database updates. So, I would recommend not going that route.

If you need to sign out a user across all logged-in sessions, use a revocation list based on UID, rather than token-id.

Re:Don't use JSON web tokens for sessions by merb on Tuesday June 14, 2016 @12:56PM (#11903359)
yep probably the better idea. eventually we combine sessions and JWT Tokens. The session id is kind of a refresh token that refreshes the token if it was expired and the user didn't generate a new token in less than one minute. than it will use the session id will query the database and create a new token if the session is still valid.
Re:Don't use JSON web tokens for sessions by ponyous on Monday June 13, 2016 @06:52PM (#11898407)
Maybe you could salt the secret per user and store it in the DB. This would allow users to have a feature like "Logout from all devices". I am not sure how you would query the database to get the salt? JWT as key and salt as value? Or maybe sending userId with each request?

Anyone know any good articles I can read on the topic?

Re:Don't use JSON web tokens for sessions by sk5t on Tuesday June 14, 2016 @12:03AM (#11899682)
The extra salt is probably unnecessary if you require (and validate) not-before and not-after dates on each token. I couldn't say more without knowing the details of your implementation, but "secret salt" strategies often are a band-aid over some more fundamental problem.

Whether it is good to bind the JWT to some combination of user-agent, device cookie, IP address (not recommended) or whatever, is a separate topic...

Re:Don't use JSON web tokens for sessions by tym0 on Monday June 13, 2016 @06:57PM (#11898439)
Wait. You have individual salt for each user that you store in your DB?
Re:Don't use JSON web tokens for sessions by NathanKP on Monday June 13, 2016 @07:23PM (#11898579)
More than that. A salt for each "session".

Each JWT contains two pieces of info: user ID, and salt. This stops the JWT from being a deterministic token that is always the same each time a token is generated for a specific user.

It also allows invalidation. On each request a middleware checks validity of the salt from the JWT. A Redis cache layer here makes this a 1-2ms operation and easy to scale. If you need to invalidate a JWT delete a salt and the respective token is now invalid. Or delete all salts for a user to invalidate all their sessions.

Honestly this use of a JWT is basically just a lightweight session that passes the session ID via a technique that isn't insecure by default like cookies are. Rather than having to opt in to CSRF protection your stuff is hard to CSRF unless your application persists the token insecurely.

Re:Don't use JSON web tokens for sessions by kelson on Monday June 13, 2016 @08:59PM (#11899041)
Salt is random data used to cryptographically sign or encrypt data. It sounds like your JWT consists of a userID and a sessionID (stored in Redis).

Why not just store your sessionID in a cryptographically signed HttpOnly cookie? In most use cases, it'd be less ambiguous, better protected from JS attacks, and equal-or-less vulnerable to CSRF.

https://en.wikipedia.org/wiki/Salt_(cryptography)

Re:Don't use JSON web tokens for sessions by joepie91_ on Tuesday June 14, 2016 @03:20PM (#11904576)
> This is simple not true. You ALWAYS will sign your tokens with a well known secret, you could eventually even add some salt from a database to it.

This refers to invalidating individual tokens. I've just updated the title and text in the post to clarify that.

> Compared to what? Actually JWT will have the same secureness like Bearer Tokens or Cookies, wherever you store it, its not `less` secure. Horrible article points here.

Compared to storing something in a cookie. The article explicitly states that this concerns JWT tokens that are not stored in a cookie. And comparing "JWT vs. Cookies" makes absolutely no sense, they're different kinds of things.

> They take the same amount of storage than signed cookies, wuhu I use JWT so often and I NEVER exceeded the cookie limit, but I wouldn't store them there anyway.

Again - the article explicitly states that this refers to stateless tokens, ie. where the data is contained in the token itself. Did you actually read the full article, or just the headers?

> JWT is as secure as any other solution and this article proves it since he isn't well informed, he just throws a bunch of stuff out and tries to be "an expert". Btw. every other solution is really dangerous as well, especially Cookies could be a total mess of security problems. The same could actually happen with Bearer Tokens.

Personal attack and hand-wavy statements without ever actually addressing any specific security concerns. Take that elsewhere. I'm here for technical discussion, not for throwing shit.

> My toughts are use the thing your most happy with and the thing you understand

No, that is not how security works.

> and the thing you can implement with code that is totally clear and especially code that is really really easy to understand. And actually JWT will mostly win this battle.

No, it won't. The typical framework will only require you to load a single plugin to get sessions working, and literally nothing else. JWT tokens require manual handling.

> I've seen a lot of people just using Session Cookies from their Framework, but eventually have no idea about their risks, they have lots of CSRF all over the place

That is a separate problem, and you don't solve that by storing your session IDs differently and trying to sidestep it. You store it by actually mitigating the problem you are having, which means adding CSRF tokens.

That's the only actually secure solution to this problem - "manually handling sessions" and "secure session storage" are mutually exclusive, and automatically handling sessions will always be vulnerable to CSRF problems.

> or using a too small ID or eventually the ID is not really random.

Use a well-tested implementation - as, again, I have stated in my article - and this will not be a problem. Don't roll your own session implementation.