12 ms·
Don't use JSON web tokens for sessions
- grardb 10y agoI'm working on a personal project and use JWT for sessions. The main reason I did this is that my understanding is that it makes it much easier to implement sessions on mobile apps. Is this true? If so, should I continue using them? If not, why do I think that, and how can I future-proof my API with mobile apps in mind?
- floatboth 10y agoDoesn't matter. JWT can be read on the client, but it's not necessary. From a typical client's point of view, the auth token is just a string. Doesn't matter if it's a JWT or a random string. The difference is on the server side — checking a signature vs. looking up in a database.
- Kiro 10y agoHow else would you do it if your backend is a REST API and you want to keep it RESTful? JWT seemed like a good solution until I read this.
- rahkiin 10y agoYou would do it by adding a Redis server that stores stateful sessions (mentioned in the article). I however disagree with most of the points made in the article, and use stateless JWT myself.
- Kiro 10y agoWouldn't that violate the RESTfulness? I thought stateless was one of the criterias.
- betenoire 10y agoIt depends on how you define your terms. If you think of the RESTful API and the Authentication mechanism as two separate systems, you can have your cake and eat it too. We use stateful JWT to "fail fast". That is, we can quickly reject invalid authentication, but we still look up the hash in the database before we actually use it. Our systems that do API and Auth are separate enough that the stateful/stateless distinction isn't useful.
- deleted 10y ago[deleted]
- monknomo 10y agoPeople seem to really wiggle around what constitutes state, when it comes to auth/autz and REST. Some people seem happy with a tiny amount of state to manage user sessions, which makes REST harder. Other people use tokens of one flavor or another, which may have more security vulnerabilities than conventional sessions, although I'm not convinced. Shared secret HMAC style is another alternative, although I'm not clear how to make that work with javascript clients in browsers. Some people just throw the whole authentication question into headers and do basic auth.
- rahkiin 10y agoYeah, I guess it is. I only use redis for a simple cache and for worker queues. For authentication I use JWT. I store the user permissions inside the token, purely to be used by the client side (for showing/hiding interface elements). Permissions in the backend are over the database. So I tried to minimize the revoke-problem.
- mstade 10y agoThe stateless constraint is perhaps the most misunderstood part of REST. Fielding's dissertation states that in a REST system the messages (i.e. requests/responses) must be stateless, but clients and servers are free to keep whatever state they like. What is meant by stateless here is that you don't need additional state than what's described in the message in order to understand the message itself. For example, a message that's missing the `Content-Type` header, but includes a body, should be rejected because you can't be sure of the body's content type. If you're expected to infer this information, in order to understand the message, the system isn't adhering to the stateless constraint. Cookies that have session IDs, that are then parsed and mapped to state on the server side, aren't violating the stateless constraint of REST because the message contains all information necessary to understand the message itself.
- llmfei 10y agoForget this article. He just doesn't like everybody uses JWT instead of cookie in any case. I still think JWS is a good choice for REST API in stateless session. I don't like to setup a redis server. What you need to do if the redis server cannot support so many users? So use JWT to keep stateless is a good choice.
- alfiepates 10y ago> He just doesn't like everybody uses JWT instead of cookie in any case. Why would anybody care about how you implement something in your application, unless they have a concrete reason that your implementation is less than ideal? > What you need to do if the redis server cannot support so many users? Scale up your infrastructure. You're need a LOT of users before this starts being an issue. > So use JWT to keep stateless is a good choice. The article explains why this is a bad idea... unless you can explain where the article is wrong? EDIT: Got caught in the middle of a thought, apologies.
- hackerboos 10y agoYou should probably be using refresh tokens (https://auth0.com/blog/2015/10/07/refresh-tokens-what-are-they-and-when-to-use-them/ https://auth0.com/blog/2015/10/07/refresh-tokens-what-are-th...) to invalidate sessions on a change-password event for example.
- neya 10y agoI am writing my own framework in Scala and I found a similar good article on this topic: https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage https://stormpath.com/blog/where-to-store-your-jwts-cookies-... But then, I'm now even more confused as the others here. How exactly am I supposed to secure my REST API now?
- CiPHPerCoder 10y agoUse sessions for client->server and OAuth2 for server->server.
- neya 10y agoThanks!
- cel1ne 10y agoPostgrest (http://postgrest.com/ http://postgrest.com/) uses JWT to switch between database roles.
- kevinastone 10y agoI think this assumes that people are switching from server-backed sessions to JWT. I'd expect instead that most people (and frameworks now-a-days) use signed cookies instead. Switching to JWT just standardizes that format a bit to allow non-web clients (like mobile apps) to use a similar session. I think Armin Ronacher's blog post[0] is a good overview on the benefits of using signed client storage for session state. [0]: http://lucumr.pocoo.org/2013/11/17/my-favorite-database/ http://lucumr.pocoo.org/2013/11/17/my-favorite-database/
- CiPHPerCoder 10y agoJWT is often used as an implementation of signed cookies. Also, don't use signed cookies unless you have a crypto expert on staff.
- spriggan3 10y ago> Also, don't use signed cookies unless you have a crypto expert on staff. As opposed to what ? re-implementing cookies from scratch with JWT ? JWT is a dangerous system because it's even harder to get things right. Cookies and their flaws have been documented for decades, no need to be a crypto expert to sign cookies.
- CiPHPerCoder 10y ago> no need to be a crypto expert to sign cookies You literally just said the equivalent of "no need to be a crypto expert to implement cryptographic signatures." Please don't do that without a crypto expert on staff. They'll be able to avoid side channels that non-experts will never even imagine. To wit: http://blog.ircmaxell.com/2014/11/its-all-about-time.html http://blog.ircmaxell.com/2014/11/its-all-about-time.html It's just a bad idea all around.
- pfooti 10y agoWhat I do: I use tokens (rather than cookies), but I don't use JWT, for some of the reasons listed in the post, such as "can't expire" and "data goes stale". Instead, after authenticating a user, I issue a long piece of random (256 bits of random packed into a base64 string) to the user. I use the same string as a redis key whose value is the actual user ID of the authenticated user. That way the front end can pass the token to the back end, I can authenticate and authorize using the redis data (I could store more data in redis, but instead I hit postgres for any other data about the user, such as admin roles, when needed during the authorization process). It's true that this doesn't make you invincible to CSRF or XSS - any attacker who goes through the trouble and gets access to the token via MITM (although I only use HTTPS, that's not a guarantee) or by injecting javascript in the webapp itself (through user-editable content from a malicious user), that attacker suddenly has full access to the user's account. Still, it's a pretty reasonable way to deal with session problems. I also set expiry timeouts on these tokens and can delete them manually if a user wants to end all sessions (say on password change). Deleting by value match isn't super-straightforward in redis, but it's also possible with a bit of LUA.
- monknomo 10y agoI thought you could include a tamper-proof expiration time in the payload of a JWT token? It also seems like data-staleness could be addressed, perhaps by including a hash of relevant data and invalidating/reissuing a token when the hash changes?
- pfooti 10y agoYou can include a tamper-proof expiration time in JWT, but you cannot early-expire or extend that JWT easily (you could always pass back a new, extended one transparently). But in my system, I just keep expiring the redis key for 25 hours from now each time I touch it, so users' authentications expire after 25 hours (after which point they have to go back through username/password or OAUTH, etc). You can easily change 25 hours to 4 days or a month or whatever.
- bdamm 10y agoCSRF isn't about content injection or acquisition of session tokens. I think you probably know that but the way you describe "doesn't make you invincible" I'd say a little more strongly; it doesn't do anything at all to prevent CSRF (or XSS!)
- luhn 10y agoThis articles doesn't acknowledge where JWTs really shine: Authentication across a cloud of services, esp. a microservice architecture. JWTs allow a session to be shared across all of the services without any shared state.
- foxbarrington 10y agoTotally, we started doing that and haven't looked back. Btw, if anyone is looking for an easy way to get going with Node.js check out https://github.com/davidguttman/authentic https://github.com/davidguttman/authentic
- joepie91_ 10y agoI intentionally didn't address this in the article (and went for the "download server" example instead), because there's too much risk of people implementing my (simplified) description verbatim, and ending up with a whole host of security issues. To address your usecase: This is perfectly possible without using JWTs as a session store. Your individual services will be either stateful or stateless. If they are stateless, you can simply use single-use tokens that are issued by the application server, and the entire concept of "sessions" doesn't exist as far as that service is concerned. The only thing it cares about, is whether any particular one operation is authorized. If they are stateful, you can simply maintain a separate session for each of the services. You then use a short-lived JWT token (issued by the application server) to authorize the creation of a session on a non-application-server. The client exchanges this for a session on the non-application-server. This way you essentially get the best of both worlds. Of course that leaves you to still have to implement (relatively complex) revocation infrastructure yourself for the stateful services, but that's inherent to a distributed architecture.
- gouggoug 10y agoIt does actually acknowledge it, at the end of the post: "So... what is JWT good for, then?"
- ZoFreX 10y agoYour architecture being microservices doesn't change the problems with using JWTs (or any "session" system based on signing things): you can't revoke them. I am pretty confident being unable to revoke tokens will start to be a problem with any sufficiently large websites: you don't just need to scale in terms of traffic, but also in terms of people doing bad things. If you're at this sort of scale, adding in another service that validates sessions is not a lot of work. Either your microservices that need authentication could have a library added to talk to this service, or you could put everything that needs auth behind something that validates the requests as they come in. Vulcand looks like it makes this easy (I haven't used it personally, but I've worked on a system that works similarly using an F5 device). Sooner or later, you _will_ regret not being able to revoke sessions.
- EdSharkey 10y agoSo, if I'm reading the advice right, then ... * Using JWT for authorization, particularly for one-time use == GOOD * Using JWT to represent long-lived persistent session state == BAD and, always transmit your tokens in all directions over HTTPS. This seems like useful advice given all the reasons put forward. Do I understand correctly or did I miss anything?
- CiPHPerCoder 10y agoThat's it in a nutshell. A lot of developers also misuse JWT in strange ways, and the meat of this article was responding to those weird/unsafe use-cases.
- dabernathy89 10y agoHaven't used JWTs myself, but whenever I read an article or tutorial about them, it's always in the context of replacing session cookies.
- joepie91_ 10y agoThat's pretty much a perfect summary, yeah.
- mstade 10y agoYeah, pretty much. JWT is a very good and useful spec, I think particularly in distributed systems, but it's no panacea.
- chrisfosterelli 10y agoI disagree with his argument that JSON web tokens are "less secure". He even quotes this: > The only way to retrieve data out of local storage is by using JavaScript, which means any attacker supplied JavaScript that passes the Content Security Policy can access and exfiltrate it. In my opinion, it is MUCH easier to get a CSRF vulnerability than it is to bypass the Content Security Policy. Unless you can get around the CSP and same origin requirement, this makes web tokens far more secure. He also states that if you store your web token in a cookie you are still vulnerable to CSRF. This is only true if you are using cookie headers to send the token (which is less common), not if you only use it for storage/retrieval of the token. Lastly, he argues JSON web tokens are not easier to use, but then points out you need a dedicated Redis session store server to scale session authentications. Managing sessions in mobile apps and command line apps is a huge pain compared to JWTs. How is that easier to use?
- joepie91_ 10y agoCSRF vulnerabilities are less severe than a stolen session. I've addressed the reason for that here: https://www.reddit.com/r/PHP/comments/4nwpvg/stop_using_jwt_for_sessions/d47larg https://www.reddit.com/r/PHP/comments/4nwpvg/stop_using_jwt_... > This is only true if you are using cookie headers to send the token (which is less common), not if you only use it for storage/retrieval of the token. That's the normal mode of operation for cookies, and what you should assume the client to do. > Lastly, he argues JSON web tokens are not easier to use, but then points out you need a dedicated Redis session store server to scale session authentications. At a scale where you can't just store the sessions in the database you're already using (or on disk - see PHP), the added complexity of a single Redis server is negligible. Below that scale, you can just use your regular database, at no additional complexity cost. > Managing sessions in mobile apps and command line apps is a huge pain compared to JWTs. I've heard a few people claim this now, but none have been able to explain exactly how it's a "huge pain" or "more complex". Care to elaborate?
- SCHiM 10y agoI've tested many web applications, and around 80% of all applications I've tested contained an XSS of some sort or another, that number drops to around 40% if you only look at stored XSS & XSS in a get request. And to less than 10% when only looking at stored XSS. Unless you've used cookies with the HttpOnly flag XSS trivially escalates to session stealing. Do NOT store sessions in anything other than cookies with the HttpOnly (and really, SecureFlag) flag set. Using javascript to manage your sessions only the client side in any way is NOT secure.
- fabian2k 10y agoThe one thing that I found scary when reading up on JWTs is that there is no way to revoke them. Of course you could check them against a list of revoked tokens on your server, but then your lose the stateless aspect. So the only remaining option to revoke a JWT is the nuclear option, invalidating all JWTs at once. This seemed like a rather large limitation to me. Related to this, the ability to encode further information in the token, e.g. access rights suffer from the same flaw. If I use the tokens themselves to grant different privileges on a site, I can't revoke those privileges. I've never used them in practice, this is all just from reading about JWTs. How do people deal with those aspects in practice?
- CiPHPerCoder 10y ago> How do people deal with those aspects in practice? In one word: Poorly. There is no elegant solution outside what you've outlined here. Or: they use stateful JWTs.
- andrewstuart2 10y agoWhat you've described is literally the same tradeoff you must decide on with caching TTL, but in the arena of credential validity for signed tokens. In both cases, you're deciding how long something should be valid before it's flushed and must be renewed, or whether you should always check the source.
- vkjv 10y agoThe nice thing is that you get quite a bit of middle ground to play with performance. Examples: * Refresh TTLs that allow for some caching before hitting a DB (revoking). * Using a Bloom filter to revoke to limit the number of affected users, but also bound memory.
- bjt 10y agoJWTs can be revoked if you sign them with application_key + some_user_revocation_string. This is how password reset tokens work in Django, for example. They're signed with the app's secret key + the user's existing password hash. Once the user uses the token to change the password, the token is no longer valid.
- ubercore 10y agoSo, I've been approaching JWT as a "proof of login" essentially, to handle authentication across web, mobile apps. The only payload I use is relevant to identifying the user logged in. Session data would be handled by server-side code, though it's still early days for me so I haven't had a use for it yet. After reading this, I'm wondering if I'm misusing JWT, and should replace it for the use-case of authenticating API calls are coming from an identified user in a client agnostic way?
- joepie91_ 10y agoFrom the sounds of it, you're essentially using stateful JWT tokens. In that case, I'd recommend using a battle-tested session implementation for your stack of choice instead, if there is one - this rules out implementation errors or overlooked security issues on your end. Security can get pretty tricky. The exact token scheme you use shouldn't matter for the client. As long as the client supports cookies in some way, it'll just treat it as a dumb blob of text - only the server needs to care about how to interpret the session token.
- ubercore 10y agoI'm using actionhero for the backend. To be clear, I'm not concerned about _sessions_ so much as I'm concerned about authenticating all requests. I guess it's just still not clear to me based on the article and your feedback what the flaw is checking a valid JWT in the Authorization header to identify the user making the request? Other than the relative inability to invalidate sessions (ie, only hacky methods for achieving this)
- vonklaus 10y agothere was an article on here which I found more in depth than this, about why tokens are a good way to do auth. Im on mobile, but it was ~6 days ago if someone digs it up. However, I guess I don't understand what the actual argument is. Vue js sets the header to auth bearer and pulls from local storage. I have a token and I verify the id in the payload, the subject which is usetname, expiration and the issuer. If we assume this goes over SSL/https what is the attack vector. The other article (and this) basically say someone can run a script and get the token however it is pointed out that if soneone can run arbitrary code on your site or users machine, then you already lost anyway. What am I missing?
- merb 10y agoYou 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.
- numbsafari 10y agoYour 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.
- merb 10y agoactually 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.
- deleted 10y ago[deleted]
- andrewstuart2 10y agoI'm not quite sure the author of the article has a solid grasp of JWT, or identity federation in general given that he compares JWT to cookies (it's more like SAML than anything else). I'd highly recommend giving the RFC [1] a once-over to see what the spec is really about. > The correct comparisons are "sessions vs. JWT" and "cookies vs. Local Storage". This is somewhat true, but flawed. The better comparison is "SAML vs JWT," or "CAS vs JWT." JWT is a claim assertion standard (most often used for ID claims), and should not be compared with sessions in any way. A JWT (signed by a trusted authority) is a valid way to start a session, or to hold and transmit data for sessionless communication. > They really aren't [easier to use]. Maybe not compared to cookies, but they definitely are easier than SAML2, which they ought to replace. > I have yet to see somebody actually explain how JWT is more flexible. They have flexible claims which require no DTD; SAML does not. Cookies support this too, but they really shouldn't be part of the discussion. > Server-side expiration is preferable, in fact - it allows your application to clean up session data that it doesn't need anymore The best part of signed tokens (if you don't mess with revocation) is that you don't remember any data. You perform an identity lookup, authenticate the user, generate and sign the token, and send it off. No need to keep any data around at all, much less handle the complexity of cleaning it up. > It doesn't, really. There are roughly two ways to store a JWT: The way JWT solves CSRF is not by the way it's stored; it's by the way it's transmitted in an Authorization header, which can't be done cross-domain and won't be included by the browser (as cookies would). If you're not using JS, you shouldn't be looking at JWT at all; it's useless without it. > Users don't just block cookies, they typically block all means of persistence. Unless they're blocking JS (which would render the whole article moot anyway), then there's memory persistence for as long as the browser hasn't refreshed. This is more than enough persistence to realize the benefits of JWT (talking to multiple backends, SPA experience, etc.) Yeah, it's gone when you refresh or navigate away, but some might call that a feature. Just re-authenticate with the JWT provider and keep going. > JWT tokens are not exactly small. They're as small as a secure cookie: metadata header + data + signature. That's it. And they don't need to be communicated as part of the URL (though it's deliberately safe to do so), and should not be communicated via cookie (eliminates CSRF benefit). > They are less secure Not if they're signed and validated against trusted issuers. Which they should be. Heck, they'll even be encryptable (in a standardized way) soon. [2] Then even the browser they're sent to can't see what they contain unless it has the private key. > You cannot invalidate JWT tokens Yes, you can. Use revocation and check with the authority. Just because it's not specified doesn't mean you can't use long-standard methods (see CRL [3]) to achieve your design requirement. > Implementations are less battle-tested or non-existent As with any new technology, implementations are also new. Just like I don't have 5 years of experience with Angular 2. And a quick glance at jwt.io will show you that there are plenty of implementations available for a huge swath of languages. Seriously, read the spec, know your use cases (JWT is not a session replacement, though it could function similarly), and learn the crypto primitives that make this secure (JWT provides verifiable integrity via signatures, not confidentiality (yet) and leaves that to other layers (until JWE)). [1] https://tools.ietf.org/html/rfc7519 https://tools.ietf.org/html/rfc7519 [2] https://tools.ietf.org/html/draft-ietf-jose-json-web-encryption-40 https://tools.ietf.org/html/draft-ietf-jose-json-web-encrypt... [3] https://www.ietf.org/rfc/rfc5280.txt https://www.ietf.org/rfc/rfc5280.txt
- vladgur 10y agoIll chime in with my $0.02 * Inability to invalidate stateless JWT tokens can be more or less be remedied with a short expiration time of the token and a token refresh flow. If a token is only valid for 5 minutes, and you can only refresh the token during that 5 minute window, it greatly reduces the attack vector. If that risk is too high, you should easily implement state with the same Redis setup that author mentions * a classic CSRF example where youre logged into your app in one tab and you open a malicious link in another tab is not a threat if you, like the author suggests, use cookies for storage, but not for authentication. If you pass a token around in an "Authentication" header and have the server IGNORE the cookie which will inadvertently be sent, the request made in another tab via a malicious website is not going to be authenticated. There are definite Usability and security pros to using Session cookies for storage: * Unlike Session Storage, the cookies are visible by your application if you have two instances of it running in different tabs/windows. * Unlike Local Storage, session cookies get wiped out when the user closes their browser
- rahkiin 10y agoIf you give the tokens an expiration time of 5 minutes, the application either needs to auto-request a token every 4-5 minutes automatically using a JavaScript timer, or your session times out way too quickly. If you close the tab, you will be logged out within 5 minutes. That may not be desired in many applications.
- mstade 10y agoYou don't have to use a timer, you can also do it when you're about to use the token, or after the token has been rejected if you're so inclined. I.e. before you make a request you check the validity of the token and if it's not valid you refresh it; or if you don't do this validation you'd have to deal with the server rejecting your token, doing the refresh, and then trying the original request again.
- vladgur 10y agoThat correct. You would use the timer to auto-refresh the token. Note: if you close the tab, if you use a session cookie for token storage, its likely to remain, but like you said will become invalid within 5 minutes. If you close the browser however, a Session cookie will be deleted, which mitigates an issue in a shared setting. Depending on the requirements, you can ask a user whether they are using a shared pc or a private pc and choose cookie storage at that point.
- mythz 10y agoThis article seems opinionated without much substance and I disagree with many of the points listed. It also doesn't address using a JWT Token in a Cookie for Web Apps as recommended at: https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage https://stormpath.com/blog/where-to-store-your-jwts-cookies-... And ignores usage of refresh tokens: https://auth0.com/docs/refresh-token https://auth0.com/docs/refresh-token Easier to use JWT's are simpler when your System is composed of multiple Services as only a single Service needs to issue JWT's and provide Auth Services, all other isolated Services only needs to know how to validate a token and doesn't need other Session State or Auth configured yet are still able to provide protected Services. More flexible JWT's allow for externalized, centralized Auth where the issuing of the Token can be decoupled from validating it. It lets you easily launch new Services offering Protected API's out-of-the-box without needing to configure any Auth or persistent Session state. Data goes stale Services that care about stale data embedded in JWT's should hit the DB using the UserId embedded in JWT's, this is more "live" then accessing it from a Session which is stale from the moment the Session or JWT is created. More secure It's not less secure, and one instance where it can be more Secure if you use RSA as the centralized Auth Service can sign JWT's with its private keys and Services validating tokens with only a public key. So JWT's can be cryptographically verified it's been issued from a central authority with access to the Private Key. Whereas authenticity of Session data is not verified and can be tampered with anyone with access to the session data store. The recommendation is to use Redis which offers weak security since it's not supposed to be accessed externally so uses a simple password which is sent plain-text over the wire. Built-in expiration functionality "This is nonsense, and not a useful feature." Unhelpful Opinionated assertion slinging. Embedded expiration could be a simple constant or implemented from a Custom policy based on the User. Since this is decided by the Issuer this logic only needs to exist in one place. Works for users that block cookies "Unlikely. Users don't just block cookies, they typically block all means of persistence." Not sure where the article gets its fact checking from, but this is another opinionated assertion not backed by any sources. Cookies are blocked due to privacy issues, whereas Local Storage is used a lot more for providing rich Web App functionality. Disabling Cookies definitely does not also imply disabling Local Storage. They take up more space The space trade-off is due to enabling a more performant, scalable and flexible stateless architecture. You cannot invalidate JWT tokens Another strong assertion that is false. You can include any mechanism you like to invalidate tokens, e.g. you could embed a unique JWT Id (https://tools.ietf.org/html/rfc7519#section-4.1.7 https://tools.ietf.org/html/rfc7519#section-4.1.7) to check against a blacklist loaded in App Servers memory. Your JWT implementation could have an option to "Invalidate all JWT Tokens issued before certain date" which is similar to flushing a Session storage, i.e. all JWT/Sessions created get invalidated. The simplicity and statelessness of JWT's makes it easy to apply custom generic logic.
- jondubois 10y agoJWT makes access control super easy/efficient in some cases because you can setup middleware functions to block/allow specific connections/requests just by looking at access rights stored in the JWT token (no need to do database lookups in many cases). I disagree about using cookies instead of localStorage. Cookies with the HttpOnly flag enabled (as suggested in the article) don't work well in some environments such as hybrid HTML5/native apps (using WebViews) because of cross-origin restrictions - For an app which runs inside a WebView, the cookie will not be sent to the server if your script files are served from the mobile devices' file system - So your server will never get the JWT token in this case. With localStorage (or a Cookie WITHOUT HttpOnly), you can manually read the JWT using JavaScript and send it through - I know this opens you up to XSS attacks but it's a small price to pay. Most frontend developers accept the fact that if you have malicious third-party code running inside your app's frontend, that's pretty bad news in any case. The fact that the malicious code can access a user's JWT token isn't the worst thing that could happen - At that point, the malicious frontend code could theoretically do anything it wants with your account by hijacking your UI. The simple solution to mitigate XSS attacks is to serve all your frontend scripts from your own trusted CDNs - When it comes to vulnerabilities, there is always a tradeoff between CSRF and XSS - Personally, I find XSS threats much easier to manage than CSRF (it's a smaller attack surface). Also, you CAN invalidate JWT tokens - You can change the auth key from the server-side (thereby invalidating the signature of previously issued tokens). Or you can send JWTs with really short expiries (e.g. every 10 minutes) and then renew them on an interval (e.g. every 9 minutes) so that the JWT doesn't expire while the user is still active. There are a lot of different ways to use JWTs safely. It is not right for someone to say that a technology is bad unless they are aware of all the possible use cases for it.
- meowface 10y agoJWTs do have plenty of valid uses. I definitely agree with this point, though: >If you are concerned about somebody intercepting your [anything], you should just be using TLS instead It's weird to see a lot of devs try to reinvent the wheel and do some kind of half-assed transport encryption when they could just use TLS.
- deleted 10y ago[deleted]
- arekkas 10y agoExcept for local storage the information in this post is useless and partially false.
- bricss 10y agoSo, we should use mint vaseline for session?
- biznickman 10y agoSomewhat related to this issue, and yet another potential security issue. Like in a cache, the data in a stateless token will eventually 'go stale', and no longer reflect the latest version of the data in your database. This can mean that a token contains some outdated information like an old website URL that somebody changed in their profile - but more seriously, it can also mean somebody has a token with a role of admin, even though you've just revoked their admin role. Umm, if you are storing the roles of a user in a JWT token, I think you are doing things wrong. The point of the JWT token is not to store ALL information of a user. It's simply a way of identifying the user (their ID) and potentially offering an expiration on the token. Personally, I use tokens to make authenticated API calls but the API still verifies that the user has the required roles to take the specified action. You can then request user data when they login at the same time the token is issued to reduce request volume and then cache any user data locally (should you not want to ping the API server for user data on every request). Locally they may be displayed as an admin while the cache says so but on the API server, there's no way for them to make such requests if the role has been revoked. The greatest flaw that this article assumes is that everybody loads their JWT tokens with all sorts of personal info. This is a horrible practice. While theoretically JWT tokens support this, it's by no means a best practice. In essence, he's arguing against an anti-pattern which is already a known anti-pattern.
- alanh 10y agoPlease, for quotes, use a > and/or asterisks, but not a leading space. That triggers formatting that doesn’t wrap. > This is much nicer
- cortesoft 10y agoThis part: "In practice, however, it's fairly trivial to replace the session mechanism at a later point, with the only cost being logging out every user once, when you make the transition." Is not true in terms of needing to log everyone out once. It is pretty easy to write transition code, to accept the old style session and return the new style. You might not be able to transition everyone (if they don't use the session in the time you have your conversion code running), but you will get MOST people, and certainly most active users.
- homakov 10y ago>You are essentially powerless, and cannot 'kill' a session without building complex (and stateful!) infrastructure to explicitly detect and reject them, defeating the entire point of using stateless JWT tokens to begin with. just autoincrement nonce=123 and revoke it any time. Nothing complex about it. >it can also mean somebody has a token with a role of admin, even though you've just revoked their admin role. nobody stores user mode in session, that's what DB for. >but without the battle-tested implementations. "I don't know what's wrong but I'm kinda afraid to try". Best argument so far is that it's indeed longer. Bottom line: Use JWT for sessions, they are awesome! In Rails we're using similar mechanism for years already.
- kelson 10y ago> just autoincrement nonce=123 and revoke it any time. Does that revoke all tokens (shared "nonce") or update the token on next authentication? Would this "nonce" be stored in the database? > nobody stores user mode in session That's optimistic: https://github.com/akagadovskiy/ng-admin-jwt-auth/blob/master/js/authService.js https://github.com/akagadovskiy/ng-admin-jwt-auth/blob/maste... > > but without the battle-tested implementations. > "I don't know what's wrong but I'm kinda afraid to try". Battle-tested implementations have dealt with (at least some of) these threats previously. New approaches often miss the lessons of past efforts, leaving themselves vulnerable to old attacks.
- homakov 10y ago> Would this "nonce" in the database? Only in revoked list=1,2,5,7 etc. Unlike storing all sessions, you only store revoked integers which takes way less space and achieves same revocation you wanted. > That's optimistic Nobody should store > leaving themselves vulnerable to old attacks Every new line of code is probably a vulnerability. That's life. BTW JWT indeed had some super stupid bug with alg=NONE before, and I would simply throw away "header" from JWT
- Negative1 10y agoThis article is deeply troubling from a factual standpoint and I hope people do more research when considering JWT. Points; 1) His terms are confusing and just plain wrong. Backwards even. For example, he calls storing an id in the token and session data server-side as stateful. That is incorrect; there is no state stored on the client, it is all server-side. That is by definition a stateless session token. 2) A lot of his claims of why people recommend JWT are unsubstantiated and frankly, I've never heard them before (like JWT is better for mobile... what)? Maybe I would feel better if he provided references but a lot of those points are just plain misinformed (or imo, made up). 3) "You will not need stateless sessions" is like saying O(n) performance is usually good enough. Well ok, until it isn't. Don't assume some worst case performance on your site won't occur. Build defensively, knowing where you might have a bottleneck (DB I/O for instance). It's not just 'future proofing". It's good engineering, damnit. 4) It's hard? Give me a break. 5) It's inflexible? You can store an entire JSON object in a JWT. That is incredible flexibility. 6) It's not that secure (whereas cookies in his opinion are)? This is just blatantly false. Ok, I'm tired of debunking this article. Plain and simple, this article is not just misinformed but dangerously wrong. I appreciate Sven trying to share his insight with the community of developers but most of what he says is wrong. I use JWT for stateless session management backed by some clever database optimizations (at least I like to think so). If you want to know more ask, but please, do not use this article to guide your decision on whether to use JWT (or a similar secure token scheme).
- tszming 10y agoWhile several points in the article are arguable but I agree not using "JWT for managing user sessions in their web applications". If you need to add extra / custom / unproven mechanisms to invalidate JWT tokens and this defeat the purpose of the simplicity of using Stateless JWT - people are using sticky sessions or session servers to solve the scalability problem of user sessions in web apps pretty well and most frameworks bundled battle-tested libraries to do so long time ago.
- arisAlexis 10y ago1. Mobile sessions are not realiable 2. You dont need to run redis (with service discovery!) I fail to see cons.
- bricss 10y agoFacepalm
- uNki 10y agomy approach: after authentication i'm generating a JWT and send it to the client that stores it in LocalStorage. On the server side I'm using a memcached database that stores a key-value-pair (JWT and some config stuff that shall not be visible on the client side..) for 30 minutes and then deletes it. The JWT is sent with every client request in the Authorization header. A function checks if there is any key-value-pair in the memcached database that matched the JWT (key) and if that JWT is valid. After that it continues or denies the request. The client requests a new JWT after 29 minutes. If the client is offline and doesn't request that new JWT, the old JWT is killed after 30 minutes, anyway. I can't see any other attack vector than XSS - which I'm trying to avoid as hard as I can. But lets face it: IF you have a XSS problem, then you'll have it anyway, with JWT or without. If someone has full access to the JavaScript of your website, he/she can capture any authentication data you are going to send over the wire, unless you use cookies (where you'll have the CSRF problem..). SO, I think it's pretty safe if you get your XSS protection right. Opinions? Thank you :)