6 ms·
Not true. Encode a token and validate it against a constant, which you change in case of a compromise.
by tehlike 8y ago
Not true. Encode a token and validate it against a constant, which you change in case of a compromise.
- anonymousJim12 8y agoHow do you encode it in such a way that you can invalidate individual tokens? How do you distribute that information among your services?
- dperfect 8y agoIn the past, I've compared the "iat" (issued at) value with a column in the users table called "invalidate_tokens_before". If I need to invalidate tokens for a user (for my use case, it would always be all tokens for a user at once), I just touch that timestamp column. True, it still required a db lookup (one that happens anyway), but I found that easier to manage than storing and managing session tokens.
- ivanhoe 8y agoAnd how is that better than using sessions in the first place? What is your gain?
- the_af 8y agoDoesn't the author cover this in their rebuttal (http://cryto.net/~joepie91/blog/2016/06/19/stop-using-jwt-for-sessions-part-2-why-your-solution-doesnt-work/ http://cryto.net/~joepie91/blog/2016/06/19/stop-using-jwt-fo...), "Your blacklisting/revocation server goes down, now what?". Everything from there goes to "Congratulations! You've just re-invented sessions (only with a less battle-tested implementation) and gained nothing in the process" (Sarcasm is from the author's post, not mine!)
- dperfect 8y agoI don’t think of JWT as a replacement for db lookups or storage, but they do provide a convenience in not having to store and manage all sessions in the database[1]. I’ve done it both ways, and as long as you’re careful about a few of the potential security issues with JWT (solve it once, put it in a reusable module), it actually does save a considerable amount of code and complexity on the server side. Also, in my case, "your blacklisting/revocation server goes down" means the whole application is down anyway, so that's kind of a moot point. You may disagree, and there are valid reasons to avoid JWT. I'm just saying that under the right circumstances, it can be useful. [1] The author claims that JWT isn't any easier, but then later says things like "Expiration can be implemented server-side just as well, and many implementations do". That's true, but it is something extra you have to implement yourself, i.e., not easier (for that feature at least).
- SiempreViernes 8y agoThe author is pretty clearly comparing using jwts with using some framework provided session solution, not having you implement sessions from scratch. So just use a session library with expiration implemented, don’t take one without and add it on yourself.
- the_af 8y agoExactly! Because if you're implementing everything from scratch, you'd have to check the JWT's expiration yourself... it won't automatically expire by itself otherwise.
- dperfect 8y agoAgain, I’m not arguing that traditional sessions are bad and JWT is categorically good. Of course, if everything is already implemented for you[1], then ease-of-use is less of an issue, but there are valid use cases where JWT makes sense (it isn’t categorically “bad” as the author tries to show). For some of my particular use cases[2], I happen to prefer the JWT approach (despite all the points given in the article, and after auditing the libraries used). For others, I definitely prefer traditional session tokens. [1] Just because it’s been implemented by someone else, the complexity of that code still falls on you - especially so with something as critical as authentication. It’s not automatically “easy” because someone else implemented it; I’ve seen some pretty terrible security issues in both JWT libraries (e.g., insecure defaults) and framework-provided session management libraries. [2] Guess what? If you have tens or hundreds of millions of users, managing sessions and expiration can be a bit of a pain. Example: to keep things performant, you'll want to periodically clean up your session store (rather than just invalidating at lookup). Congratulations - now you have a background worker and the complexities of dealing with that at scale. Point is, even with nice framework-provided libraries, managing session tokens on the server can add considerable complexity.
- the_af 8y ago> there are valid uses cases where JWT makes sense (it isn’t categorically “bad” as the author tries to show). The author does sound negative, but doesn't claim JWTs are categorically bad; he actually mentions cases where JWTs are useful: when they are used as single-use tokens. The author claims JWTs as sessions are too problematic to be useful. > I’ve seen some pretty terrible security issues in both JWT and framework-provided session management libraries. It seems to me the author is arguing JWTs (used as sessions) are more error prone and less battle tested than traditional session management. So if you've seen terrible security issues...
- joshstrange 8y agoThe way we do it is with a long lived JWT (LLJWT) and short lived jwt (SLJWT). Our LLJWT lasts for a long time (think years) and is only able to to request a SLJWT, it alone has no abilities. Inside the LLJWT we store a UUID that we also store in the DB. The SLJWT is only valid for 1hr (we are testing on bringing that down to like 10min or so) and when it expires you have to use the LLJWT to request a new SLJWT. If at anytime we determine that there is abuse going on or someone wants to "remotely sign out" of a device they can invalidate the LLJWT and the next time it is used to request a new SLJWT it will be rejected.
- icebraining 8y agoIf you need to access the DB to check if you can emit a new SLJWT, what's the point of the LLJWT? Why not just store that UUID by itself? The SLJWT does seem useful, but 1h seems too much; if I fear someone might be (for example) accessing my email account using a stolen or hijacked device, they can do plenty of damage in that time. Do you make it clear to the user that their request for a remote sign out might take that long to be applied?
- joshstrange 8y ago> If you need to access the DB to check if you can emit a new SLJWT, what's the point of the LLJWT? It doesn't have to hit the DB, it could hit memcache or similar caching layer. It also means we could separate this table out from our main DB. We have done neither because it hasn't been an issue (performance-wise) yet. > Why not just store that UUID by itself? We could do that, our thought process was that we wanted everything to be a JWT and we liked the ability to, given a JWT, know who it was issued to, when it was issues, and when it expires, all without going to the DB. > The SLJWT does seem useful, but 1h seems too much; if I fear someone might be (for example) accessing my email account using a stolen or hijacked device, they can do plenty of damage in that time. Do you make it clear to the user that their request for a remote sign out might take that long to be applied? Totally agree on 1hr being too long and that is why we are planning on lowering it. We have technical reasons (legacy apps that we are trying to get updated) that will not work with lower than 1 hour (I won't bore people here with the details and there are workarounds but we haven't implemented them yet)
- lvh 8y agoSo you're saying you can have sane sessions as long as you have some server-side storage? :-)
- tehlike 8y agoYes, of course, jwt can facilitate that. Using it as a replacement is not good, i agree.
- jrochkind1 8y agoBut what value is it adding over ordinary 'bearer token' sessions in that case?
- Spivak 8y agoWhen you aren't invalidating tokens your app server can serve all static but restricted content without checking with the DB.
- deleted 8y ago[deleted]
- zhobbs 8y agoWith this method isn't the downside that you have to invalidate all tokens, and not just the attacker's tokens?
- gammateam 8y agowhich isn't bad because all the processing is done client side anyway.
- merlincorey 8y ago> which isn't bad because all the processing is done client side anyway. I believe people are downvoting you because you may have overlooked the processing that must happen on the server to encode the token in the first place.
- mschuster91 8y agoOr, implement a "master token" scheme: have a long-lived master token, which is used only for generating short-lived (e.g. 5 min) tokens that are actually used for authentication/authorization at the API endpoint. User gets banned or privileges revoked? Fine, revoke the master token on the authentication server and after 5 minutes at the latest, the user is locked out as he cannot get new valid short-lived tokens. Sessions aren't difficult - as long as you stick to one language and environment (e.g. PHP). But as soon as you throw in for example Java to communicate with a SAP backend (as an online-shop system might need to), nodejs for a "support/sales chat" system and whatever, a JWT scheme is easier to implement.
- nine_k 8y ago> Fine, revoke the master token This is exactly the ability which JWT lacks. You can, of course, combine a session ID (checked against a DB) with a short-lived token (stateless, with expiration time encoded). This will allow to only check the session against a DB if, say, more than 30 seconds has passed since the previous check. It helps with spiky traffic, and still allows to invalidate a session soon enough for practical reasons.
- vegardx 8y agoAnd this reduces complexity of all backend systems, as they only have to deal with one mechanism for authentication and authorization.
- martin-adams 8y ago>> Fine, revoke the master token on the authentication server and after 5 minutes at the latest That might be fine for a lot of use cases. But anything that can steal money using that token and 5 minutes is a very long time indeed.
- mschuster91 8y agoBut anything that can steal money using that token and 5 minutes is a very long time indeed. Then implement a check for the token in destructive operations. Should keep the performance impact pretty low.
- the_af 8y agoDoesn't the author address this in their "Why your solution doesn't work" flowchart? Everything ends up a reinvention of traditional sessions, only with a less battle-tested implementation.
- drinchev 8y agoWhat's the point of having a token if you need to check it with a database on every request? Instead of `SELECT isValid from tokens where token="<TOKEN>"`, why not `SELECT user from sessions where session="<COOKIE-SESSION>"`?
- enraged_camel 8y agoExactly, the moment you add statefulness you've basically reinvented session authentication.
- Alex3917 8y agoThere are a lot of problems with storing cookies when the front end and back end are hosted on different domains though. That is the main reason why people use JWTs with SPA apps, because otherwise it wouldn't really be possible to serve the front end from a CDN. Most people using JWTs aren't using them because they're stateless, but rather because it's the only way to solve the problem.
- joking 8y agoWith jwt you have a standarized way to get the data on the client side for example.
- davidwparker 8y agoWhy are checking against the DB here? Parent said a constant. You'd just check the constant value within the JWT vs the constant on the backend, and update the backend constant to invalidate.
- the_af 8y ago(Correct me if I misunderstand you) If you check against a single constant in the backend, are you invalidating all JWTs for all users whenever you want to invalidate only one? Even if you keep a blacklist of invalidated JWTs, how do you keep it up to date? How do you distribute it? What happens if the blacklist becomes unavailable for whatever reasons?
- 8y ago
- EpicEng 8y agoIn which case you wouldn't use JWT tokens at all...