TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

JWT Tokens are NOT safe

106 点作者 node-bayarea将近 4 年前

37 条评论

ibraheemdev将近 4 年前
This doesn&#x27;t only apply to the way JWT tokens are usually used for sessions (no persistence). The default session store for Devise (Rails) and .NET Identity is cookies, on the client. They are encrypted with a secret key and decrypted for authentication. Identity in particular allows you to store any number of &quot;claims&quot; in the cookie, such as a username or role. Because the cookies are signed and HTTP only, this is safe from attackers, but this method, along with pretty much any method that isn&#x27;t storing some sort of state on the server, has the same 3 problems listed in the article.<p><pre><code> 1. Logout doesn’t really log you out! 2. Blocking users doesn’t immediately block them. 3. Could have stale data </code></pre> I know there are ways around this with a really fast refresh time, or as I&#x27;ve heard, storing some sort of signature in the cookie, but I personally prefer a plain old server-side session store with something like Redis, or even just an in-memory HashMap. Authentication doesn&#x27;t have to be that complicated.
评论 #27626254 未加载
评论 #27627530 未加载
tytho将近 4 年前
In general, I agree that sessions should be opaque tokens stored in an http-only, strict same-site policy cookie. I just had a few problems with a couple of the arguments:<p>&gt; 3. Could have stale data<p>The only use case I&#x27;ve seen for storing authorization information in a JWT is for something like OAuth2 scopes, which is different than strict authorization rules. They&#x27;re more like delegate rules, but you should only treat those as a first line of defense before you do the checks that the authorizing user actually has access to.<p>Also, it&#x27;s just as easy to let a redis cache go stale. Seen it more than once with this same security issue.<p>&gt; 4. JWT’s are often not encrypted so anyone able to perform a man-in-the-middle attack and sniff the JWT now has your authentication credentials. This is made easier because the MITM attack only needs to be completed on the connection between the server and the client.<p>If someone can MITM your connection in plaintext, they have your credentials, whether or not you use a JWT. Yes, any information you encode in a JWT is plaintext, so if you put personal information in there, consider it leaked. Am I missing the argument here?
davis_m将近 4 年前
Holy hyperbole, Batman.<p>This is just a straight marketing post for Redis.
评论 #27626049 未加载
评论 #27626255 未加载
0x5FC3将近 4 年前
&gt; <i>JSON Web Tokens (JWT) are Dangerous for User Sessions—Here’s a Solution</i><p>Actual title on the website.<p>Edit: To watch clickbait work in real time, check OP&#x27;s submit history.
评论 #27626184 未加载
评论 #27626497 未加载
RHSeeger将近 4 年前
&gt; Security should be binary. Either technology is secure or it’s not.<p>From my experience, that&#x27;s not the case for almost anything. In fact, I&#x27;d consider it a dangerous position.
评论 #27626232 未加载
评论 #27626070 未加载
评论 #27626281 未加载
评论 #27625960 未加载
评论 #27626260 未加载
评论 #27626272 未加载
colesantiago将近 4 年前
OK, but what&#x27;s the <i>real</i> alternative here? I&#x27;m sick of these JWT hate articles on HN all the time with no universal solution.<p>Why not just use cookies and be done with it? This looks like an advertisement for Redis Enterprise.
评论 #27626034 未加载
评论 #27626033 未加载
评论 #27625983 未加载
评论 #27626067 未加载
评论 #27625981 未加载
评论 #27626175 未加载
评论 #27626148 未加载
评论 #27626146 未加载
评论 #27626351 未加载
评论 #27626481 未加载
评论 #27626066 未加载
评论 #27626382 未加载
whakim将近 4 年前
I actually find this post&#x2F;ad for Redis pretty ironic, because Redis is actually a really great solution for storing revoked tokens (since you can just store the token with an expireat equal to the token&#x27;s expiry timestamp). I do think it&#x27;s a serious issue that most jwt howtos don&#x27;t mention expiring tokens and&#x2F;or refresh tokens, but &quot;JWTs are not safe&quot; is hilariously hyperbolic.
weq将近 4 年前
TDLR; Use Redis to lookup your user data in realtime, instead of signing a token and trusting it.
评论 #27627559 未加载
yakaccount4将近 4 年前
I once watched a presentation about Macarons [<a href="https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Macaroons_(computer_science)" rel="nofollow">https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Macaroons_(computer_science)</a>] that is purportedly better than JWT. Are there any good success stories about using this?
评论 #27626019 未加载
pengwing将近 4 年前
Not bad for an advert. If you are interested, here is a short guide how to actually implement JWT securely:<p>- Make the JWT short lived ( 5 minutes)<p>- Re-freshing the JWT should involve server state (DB hit every 5 minutes, not every request)<p>- Protect highly-sensitive actions (typically overwrite&#x2F;delete, but not read &#x2F; non-overwrite) by requiring a fresh token.
评论 #27635920 未加载
echelon将近 4 年前
Once you reach this level of enlightenment (&quot;any session should be revokable and fail closed&quot;), there are still higher levels of abuse you&#x27;ll need to prevent.<p>Let&#x27;s say you keep your user sessions in Redis and replicate active-active between multiple regions. Your service allows for more than one active session per user, and has a second index of such &quot;live sessions&quot; so that users can terminate all of their sessions at once (eg. &quot;Log out all of my devices&quot;).<p>You use optimistic concurrency to update multiple indices and pieces of information. Session mutation events and validations can occur anywhere.<p>What if an attacker slowly logs in thousands of different accounts, hundreds of sessions apiece, then logs everything out in unison?<p>Redis is single threaded, and all of your validation reads are going to get jammed with impossible to clear logout events. Replication is going to play these events out in all of your Redis clusters, meaning each of your regions will fall over. Nothing in logged-in flow can be processed, and you&#x27;re stuck.<p>That was fun to fix.<p>I&#x27;ve got so many horror stories... Redis is great, but engineering at scale is tough even with great tools.
barbazoo将近 4 年前
JWT, while having shortcomings have the advantage of decoupling systems by enabling token validation and user data retrieval without having to communicate with the auth service or the database directly. Worst case, with the approach from the article, every component has to make a call to the database, becoming dependent on the data schema, etc.
benlivengood将近 4 年前
If an application needs a total order over authentication,authorization, and transactional events then redis doesn&#x27;t cut it either. Take this scenario:<p>1. User A creates resource X<p>2. User A sets X=1<p>3. User B fails to set X=5<p>4. User A transfers ownership of X to B<p>5. User A fails to set X=4<p>4. User B sets X=2<p>This scenario happens in all sorts of applications; games, document editors, financial ledgers, forums, etc. Ownership transfer is the hardest use case to support with time-limited tokens like JWT, but even cached sessions or external security services may not be sufficient because proper ordering requires ACID compliance between security and data storage. Failing to provide a total order over auth* and modification events leads to race conditions and bugs.<p>Ownership transfer is mostly a superset of resource deletion (how long the actual resources persist in storage varies) so if an application accepts an authorization&#x2F;authentication token as evidence that a resource (including a user account) still exists it can lead to reference-after-free or stale reference bugs, especially in systems where resource identifiers can be reused, or inconsistencies and race conditions in logic that makes decisions based on assumption of event ordering, e.g. orphaning related objects that would normally be deleted when the parent&#x2F;child is deleted but which fails if the owning user no longer exists, despite the authentication layer allowing the initial deletion to occur due to stale credentials.<p>If correctness is the goal then authorization decisions need to be made in the same transaction as the action being authorized, and authentication changes need to at least occur no later than corresponding authorization changes, e.g. revoking access before deleting a user or transferring ownership or invalidating sessions&#x2F;cookies&#x2F;JWTs that can&#x27;t be updated in the same transaction.
Animats将近 4 年前
It&#x27;s an ad for Redis.<p>If you&#x27;re spending too much time looking up the credentials associated with a session cookie, you&#x27;re doing something wrong. Maybe you need a cache. Sure, sometimes it won&#x27;t be in cache, but it probably will be.
评论 #27626337 未加载
will4274将近 4 年前
These articles are uniformly terrible. They all and this one complain about stateless authentication systems and describe stateful systems as better. Probably, at small scale. Choose stateless systems for greater scale and reliability when you have to and when you have the capacity to make the careful choices and compromises that come with it.<p>But JWTs are neither here nor there. JWTs are stateless if you put the user information in them, and stateful if you put the state lookup token in them. JWTs are a format, not an authentication system.<p>Never ceases to amaze me when marketing content makes me think less of a company.
priitmaxx将近 4 年前
This is just over stated. Expiring tokens remotely isn’t that hard.
iEchoic将近 4 年前
I don&#x27;t think these arguments hold up:<p>&gt; 1. If someone gets access to your token [after you&#x27;re logged out] they can continue to access it until it expires.<p>The author goes on to say that &quot;security is binary — either it’s secure or it’s not&quot;. So... Is the token secure, or is it not?<p>If we can&#x27;t assume that we have the capability to transmit and securely clear a string from the client, the whole discussion becomes somewhat pointless because both methods of authentication are borked.<p>&gt; 2. Blocking users doesn’t immediately block them.<p>If you want to block a user, why would you block the JWT? Block the userId, or some other identifier that isn&#x27;t coupled to a transient authentication mechanism.<p>&gt; 3. Could have stale data. Imagine the user is an admin and got demoted to a regular user with fewer permissions. . .<p>This example demonstrates that this would not be good information to store in a JWT and blindly trust. Store a user identifier (or another immutable and unique identifier) and look up their permissions with that.<p>&gt; 4. JWT’s are often not encrypted so anyone able to perform a man-in-the-middle attack and sniff the JWT now has your authentication credentials.<p>Encrypting the token doesn&#x27;t make it harder or easier to sniff a token or to re-use it. Assuming the author isn&#x27;t suggesting that people are transmitting literal account credentials unencrypted, this is the same point as #1 above because encryption and signing are meant to prevent against other attacks.
rmykhajliw将近 4 年前
Looks like Redis is trying to promote itself as a session data storage. From my perspective:<p>1. There&#x27;s no difference between stealing jwt or session_id with al the problems it brings<p>2. Session in external storage is a solution for small projects like personal blog etc. because you have almost no traffic to handle. FOr example: 1kk session with an average size 1k = 1kk * 1k = 1Gb in memory storage. Not so big but you will meet all the issues of 10k connections problems when trying to build a service witch can handle this also it will consume at least 100Mb&#x2F;s bandwidth just for getting&#x2F;setting data.<p>3. Server side session a simple place to store all unnecessary&#x2F;secure data and also can grow exponentially. I saw plenty projects when in one moment session data was grown over 1Mb. So the limits of JWT is a huge plus<p>4. JWT is easily scalable solution. It works great with 1k session and with 1kk - 100kk - 1000kk sessions.<p>5. Migration. Because of limitation of server side session - plenty projects started with DB as session store just because they already have DB. It&#x27;s way of pain of migration from DB to external storage memcache&#x2F;redis then to JWT.<p>From my point I don&#x27;t see any reason to keep using server session instead of JWT.
评论 #27628045 未加载
hn_throwaway_99将近 4 年前
There are viable solutions to the JWT revocation problem:<p>1. Make JWTs short-lived (10 mins or less), and use refresh tokens.<p>2. Note that for many apps, especially native mobile apps, a user rarely, of ever, logs out. And you only need to keep a revocation list around as long as it takes a token to expire, so your revocation list is often VERY small and thus can be kept in memory.<p>3. Thus, when a user logs out, they make a call to your server, and you store the user ID and timestamp - any JWTs issued before that time are considered invalid.<p>4. Write this data to postgres in a simple table. Then, using postgres NOTIFY functionality to update all your servers with the in-memory revocation list.<p>5. When checking a JWT, you validate the signature and check it against the revocation list.<p>This won&#x27;t work in all cases if for some reason your revocation list is too big to fit in memory, but even then it&#x27;s easy to extend it to a backing store if you outgrow this solution.
jrochkind1将近 4 年前
Default rails cookie-based session storage is similarly stateless on the server, it&#x27;s just a cryptographically signed packet sent by the client. Does it suffer from the same problems? Are these problems inherent to server-stateless session solutions, is the argument that you need server state?<p>I think.. not actually. If you store the user_id in Rails session, as is typical.<p>The OP seems to be complaining about storing a serialization of the user, or the complete list of user auth entitlements, in the session, to avoid doing a user lookup at all... as is apparently common with JWT? I don&#x27;t use JWT. Can you just store the user-id in JWT instead, planning on doing a db lookup for the user? Is this not something people do?<p>Or maybe it would apply anyway, becuase you still can&#x27;t &quot;revoke&quot; a session? It&#x27;s still true that if someone snooped on your session, they could immpersonate you I think, which is also what they&#x27;re complaining about? I&#x27;m a bit confused by the threat model honestly, it&#x27;s a pretty verbose post.<p>&gt; JWT’s are often not encrypted so anyone able to perform a man-in-the-middle attack and sniff the JWT now has your authentication credentials.<p>Wait.. is he saying literally the password (that can be used to get a new JWT?) is put in the JWT payload, unencrypted? This is a thing people do, really??? It is obviously a bad idea, yeah. Back to Rails, Rails started encrypting as well as signing session cookies a while ago, because of Security, yeah.<p>The OP seems to be conflating a bunch of differnet things... which is fine if they all apply to standard commonplace uses of JWT I guess, or if JWT is too flexible and allows people to use it wrong... but doesn&#x27;t make it very clear what the problems actually are.<p>Still back to wondering if the claim is that ALL no-server-state sessions are bad, or just that JWT is a bad implementation of it, or just that JWT as commonly used isn&#x27;t being used right (like you COULD encyrpt JWT payload, but most people don&#x27;t?)<p>And... it ends up just being a redis ad, really?
CameronNemo将近 4 年前
I flagged this post for the following reason:<p><i>Please don&#x27;t use HN primarily for promotion. It&#x27;s ok to post your own stuff occasionally, but the primary use of the site should be for curiosity.</i><p>The user&#x27;s submission history is almost completely RedisLabs content.
评论 #27627768 未加载
jrochkind1将近 4 年前
&gt; If you think about it, these constant debates themselves should be a red flag because you should never see such debates, especially in the security realm. Security should be binary. Either technology is secure or it’s not.<p>Hm. I&#x27;m not sure this actually matches what I&#x27;ve learned reading from security experts....<p>What do other readers think?<p>I am sympathetic to the idea that it&#x27;s suspicious that there are so many &quot;debates&quot; about a security topic. But I don&#x27;t think security is actually all-or-nothing&#x2F;binary. It depends on threat models, risk tolerance, budget, etc.
koprulusector将近 4 年前
Anecdotally I see the source of security issues with auth[n|z] and&#x2F;or JWT in general as lack of developer education or miseducation due to pervasive misinformation that so many (inexperienced)? coders post and share on YouTube, Reddit, and blogging sites.<p>The top examples of misconceptions I see being spread:<p>- JWTs are encrypted or secure in-and-of-themselves. You CAN encrypt JWTs, though I don’t think I’ve ever seen this, and generally speaking they won’t be encrypted, just signed. The best practice is to not store private information in a JWT. I’ve seen suggestions to include PII in JWTs since “cryptography” is used - incorrectly thinking this means encryption or not knowing the distinction between encrypting and signing<p>- Base64 encoding as encryption - Posts&#x2F;videos explaining the HTTP Authorization header is “encrypted” using Base64. I have no idea where this comes from other than complete ignorance<p>- OAuth2 - I see lots of click-baity titles targeting beginner coders using variations of “How To Authenticate Your Users with [O]?Auth and JWT”, and the post&#x2F;tutorial&#x2F;video goes on to regularly conflate authentication (OIDC) and authorization (OAuth), and conflating use cases or distinction between sessions, cookies, JWTs<p>I am sorry for nit-picking, but the author says:<p>&gt;In many complex real-world apps, you may need to store a ton of different information. And storing it in the JWT tokens could exceed the allowed URL length or cookie lengths causing problems.<p>I am not sure I understand, is the author suggesting that JWTs are embedded in the URL? I’ve seen codes that are exchanged for a token embedded in URLs, but this one is new to me. I’ve only ever seen or used a JWT within the HTTP Auth header (eg Bearer &lt;token&gt;).<p>Additionally, the author says:<p>&gt;It’s been found that many libraries that implement JWT have had many security issues over the years and even the spec itself had security issues. Even Auth0 itself, who promotes JWT got hit with an issue.<p>Uh, ok, I guess since software or specifications can sometimes have a bug, they can’t ever be patched or revised with a new version, so we shouldn’t ever bother using computers… seriously, what kind of argument is this?
prpl将近 4 年前
Using JWT in the browser id an anti-pattern for a different reason: they can easily balloon over 4kB if you have groups as claims and now you got to split them and a bunch of other things that are annoying.<p>On the backend you get similar issues. Many servers default to 4kB header sizes, or 8kB, or unlimited, or anything between there. So now you get to have some fun configuring reverse proxies and node and uwsgi and tomcat and…
shaggyfrog将近 4 年前
Shitty article by a shitty user with a shitty submission history. How has it lived for so long on the front page? Who upvotes <i>this</i>?
nodomain将近 4 年前
In my mind there is always the &quot;red light&quot; recently when I see big tech companies posting &quot;technical blog posts&quot; that are just cloaked marketing stories that pitch their product. The article felt the same and my feeling was confirmed at the end. JWT is unsafe! Use Redis!<p>So it is good to see that is article already has been flagged here.
ashtuchkin将近 4 年前
I&#x27;m wondering if we can use Pub&#x2F;Sub to push revocation data to all servers. Presumably revocations are rare, plus we only need to store them only for the JWT validity period, so additional memory usage should be minimal.<p>The downside is it looks more brittle than the simpler approaches. Upside is performance plus ability to revoke tokens.
sagichmal将近 4 年前
&gt; Note that the lightning emoji indicates a blazing fast speed. And the snail emoji indicates slow speed.<p>This article was embarrassing, and makes Redis Labs look childish and inept. Whatever process resulted in this blog post should be axed immediately, and this author should not be writing anything public facing.
cj将近 4 年前
The article references 39 minutes as the upper end of JWT token expiration.<p>Is this typically the case? Or can JWT token remain valid for hours&#x2F;days?<p>(Issue being that even if you “logout” of a JWT session, the session token server-side is not invalidated as it would in a traditional (I.e. redis-based cookie&#x2F;session store))
tasuki将近 4 年前
&gt; Imagine you logged out from Twitter after tweeting.<p>I don&#x27;t use Twitter, but that doesn&#x27;t sound like the usual use case. If the device you&#x27;re using is trusted, why log out? If it isn&#x27;t trusted, why enter your credentials at all?
评论 #27633927 未加载
catamphetamine将近 4 年前
<a href="https:&#x2F;&#x2F;redislabs.com&#x2F;blog&#x2F;json-web-tokens-jwt-are-dangerous-for-user-sessions&#x2F;" rel="nofollow">https:&#x2F;&#x2F;redislabs.com&#x2F;blog&#x2F;json-web-tokens-jwt-are-dangerous...</a><p>&gt; 1. Logout doesn’t really log you out!<p>That is true, but if someone intercepts a token then they can already see all the data (or perform all the actions), even before the user logs out, so this doesn&#x27;t count as a flaw.<p>&gt; 2. Blocking users doesn’t immediately block them.<p>Lame. A simple blacklist would suffice. The blacklist entries would expire after the lifetime of a generic token. Since the blacklist is small, it could fit in server&#x27;s RAM and be fast. Or it could be stored somewhere in Redis.<p>&gt; 3. Could have stale data. &gt; Imagine the user is an admin and got demoted to a regular user with fewer permissions.<p>Lame. Just block the old token on any privilige changes. All roles are stored in a token anyway, so if a user&#x27;s priviliges change, then all the user&#x27;s tokens should be included in the blacklist.<p>&gt; 4. JWT’s are often not encrypted so anyone able to perform a man-in-the-middle attack and sniff the JWT now has your authentication credentials.<p>Not even true. There&#x27;re no credentials in the token. There&#x27;s just a user ID and that&#x27;s it.<p>&gt; It’s been found that many libraries that implement JWT have had many security issues over the years.<p>And Linux kernel has had many bugs. So what now? Not use Linux?<p>&gt; In many complex real-world apps, you may need to store a ton of different information.<p>And storing it in the JWT tokens could exceed the allowed URL length or cookie lengths causing problems. Lame. No one uses cookies or URL for that. No one stores enormous amounts of data in a JWT.<p>&gt; In many real-world apps, servers have to maintain the user’s IP and track APIs for rate-limiting and IP-whitelisting.<p>Not a valid argument. Those apps aren&#x27;t even many, they&#x27;re a very small portion. Very small, almost zero.<p>&gt; One popular solution is to store a list of “revoked tokens” in a database and check it for every call. And if the token is part of that revoked list, then block the user from taking the next action. But then now you are making that extra call to the DB to check if the token is revoked and so deceives the purpose of JWT altogether.<p>They aren&#x27;t very smart, are they? Because they don&#x27;t even see a difference between a short in-memory list and a database full of users records.<p>&gt; Bottom line<p>Bottom their ass
评论 #27626107 未加载
stillbourne将近 4 年前
Every time I start a new job I feel like I spend a lot of time trying to argue this point exactly. Don&#x27;t send a JWT to the client, just send a fucking cookie.
lstroud将近 4 年前
JWT is fine when used within an auth protocol like OIDC. It’s like claiming certificates are unsafe because I send the public and private keys.
CameronNemo将近 4 年前
Question: do these arguments not apply to any certificate authority system? Token (cert private key) lifetime, revocation lists, stale data?
cphoover将近 4 年前
This reads as redis marketing content push, probably coinciding with their upcoming IPO.
ralusek将近 4 年前
TL;DR as always, is that there&#x27;s nothing wrong with JWT. The problem is with thinking that there is a way to have an authentication token that isn&#x27;t persisted in any way, so long as you want the ability to invalidate a token (i.e. logout, user banned, password change, etc).
评论 #27629622 未加载
评论 #27626769 未加载
ppcelery将近 4 年前
maybe you can add a `sid` in jwt token, then store this sid in redis. when you want invoke a session, just del this sid in redis.
评论 #27626749 未加载