Hacker News new | past | comments | ask | show | jobs | submit login
JavaScript Object Signing and Encryption is a bad standard (2017) (paragonie.com)
84 points by IggleSniggle on July 12, 2021 | hide | past | favorite | 72 comments



    We're developing a simply secure alternative, called
    PASETO (Platform-Agnostic Security Tokens).
D. R. I. N. K. Y. O. U. R. O. V. A. L....

Hey wait a minute, this secret message is just an advertisement!


For anybody wondering, this is a reference from the cult classic movie A Christmas Story. Very funny, brings back memories


Or it's a reference to a real life marketing campaign that was referenced in that movie?

[Edit]

So I googled. Never realized that message was never a real secret code from the radio show. Sponsored by Ovaltine but apparently the creators deny having put ads in the secret messages as the movie claimed.


>Most cryptographers recommend migrating away from RSA.

They do? This strikes me as an exceptional statement that smacks of crypto fandom especially when combined with a later complaint that their favourite curve is not supported.


In my experience the recommendation to move away from RSA is only true for building entirely new systems. RSA isn't yet recommended against in the sense that using RSA (with sufficient key length, and avoiding the known footguns) to talk with systems that are too old to understand the newer curves is not considered insecure.


I know responding to my own comment is taboo, but I wanted to add some more nuance to the statement.

I think it's uncontroversial to say that RSA in practice is a fraught proposition. There are a lot of foot-guns that even the mainstream libraries don't protect you from, so just using RSA means you need to spend a lot of time making sure you're not using it the wrong way, and "how to use it right" isn't elegantly contained in a Stack Overflow answer anywhere. And because RSA comes with so many knobs to turn, it ends up being an extensive analysis task for the poor developer whose job is to write the code. I've been that developer.

However, if the choice is between (1) using RSA, with caveats, because the tech stack is already mostly RSA, and (2) updating the whole tech stack to ECC based algorithms, we are not yet at the point where option #2 is always the right answer.


RSA signatures aren't really an issue. Big, but not that easy to screw up.

The (biggest IMO) problem with RSA is that unlike ECDSA or ECDH or EdDSA it's usable for BOTH signing AND encryption, and re-using the same keys for both signing and encryption can be catastrophic (if you screw up the padding, which is another uniquely-RSA footgun). It's far, far easier to have a signing algorithm with signing keys, and an encryption algorithm with encryption keys than it is to have a single algorithm that does everything but requires the user to get all the options right. By working the same "both ways" RSA makes asymmetric key management even harder, and it's already one of the hardest parts of cryptography!


Primarily, because ECC is more efficient than RSA (which you can use to make it faster or more secure). That's particularly important for wireless devices/IoT.

A shakier reason is speculation that prime factorization could be more solvable problem than elliptic curves.


i have never seen anything anywhere advocating for moving away from RSA. i'm curious to see what their sources are for this claim.



watched the whole thing. was very informative. Actually havent used RSA in any capacity in years (AES is a lot easier to use), but always viewed RSA as a battle-tested encryption method/alg. I suppose with anything there are ways to misuse it, and RSA appears to be really easy to misuse.


I would say that it’s fairly rare that RSA and AES are really competitors for the same category of uses, as they’re asymmetric and symmetric algorithms respectively.

I would suggest that anyone who doesn’t know about the differences between these things just not use cryptography directly and instead use things like libsodium which has sane defaults and a hard to misuse api.

If you don’t know cryptography fairly well, it’s a massive minefield.


In 2005, The NSA began recommended migrating away from RSA and onto ECC algorithms for its customers' classified use cases. [1]

In 2018, it paused that recommendation, essentially arguing that if you haven't migrated already, wait until the quantum-resistant algorithms are well vetted to avoid a second migration.

1. [https://en.wikipedia.org/wiki/NSA_Suite_B_Cryptography]


Convince AWS, Azure, Google to abandon JWT for their APIs and we’ll talk.

Until then, this is pretty much noise.


And also GitHub, Gitlab, Auth0, OKTA, login.gov, Atlasssian, Kubernetes, Hashicorp, etc…

OIDC seems to be the de-facto standard today.


My understanding is the use of JWTs for session management is 99% of the time bad (tldr: you think you get "stateless" sessions but in reality you still need server side state for useful features like logging out); but its use for auth (i.e. via OIDC) is a normal and good use case.


> in reality you still need server side state for useful features like logging out

im curious about this. normally 'logging out' just involves deleting the secure http-only cookie where the jwt was stored. is there something I'm missing here?


Access revocation: sometimes it's critical to block access to an issued token, without trusting the client to comply with revocation, especially for malicious cases.

Enforcing this implies to implement access control on each (critical) request, giving little advantage to a self contained token compared to a pure stateful signed session token.


With ordinary sessions you need to store all active sessions in server. Sessions might be long-lived, may be eternal.

With JWT you need to store forcibly terminated active sessions in server. Those sessions are short-lived. So basically it's empty map.

Another solution with token is to change server key and force all short lived sessions to reauthenticate. It is not very nice, but if that's an extremely rare scenario, it might be appropriate to get rid of checking each request while still supporting forcible logout.


Yeah, if you need that kind of control over token access, then im not certain a jwt is the right tool for the job. For most use-cases a short-lived jwt is fine, as it expires in a matter of minutes, or even seconds, depending on configuration.


The ability to logout existing sessions (typically either via a manual user action or automatically upon changing/resetting their password) is a desirable feature in essentially all applications where user accounts can be compromised.

You can kind of fake this by using a short-lived JWT and constantly refreshing it, but this:

1. Massively increases server strain and bandwidth usage

2. Has problems with users less reliable connections (they'll be randomly logged out all the time)

3. Makes "Remember Me" style features impossible (unless you use a server-side store for that, which brings us back to it not being stateless)

Here's a good graph on why $method to make JWTs work for sessions is bad: http://cryto.net/~joepie91/blog/2016/06/19/stop-using-jwt-fo... (note: for some reason the website doesn't support HTTPS :( )


> 1. Massively increases server strain and bandwidth usage

A short-lived JWT that fits into an HTTP Header is not going to _massively_ increase your bandwidth usage. At most, you will end up with a single refresh request every few minutes as each short-lived JWT expires.

> 2. Has problems with users less reliable connections (they'll be randomly logged out all the time)

Usually if your request failed due to a bad connection, the client wouldn't be designed to automatically log out the user. That would be just terrible UX.

> 3. Makes "Remember Me" style features impossible (unless you use a server-side store for that, which brings us back to it not being stateless)

Incorrect. A short-lived JWT tied to a refresh token allows for a remember-me style feature by checking account access when issuing a new JWT token.


AD: I wrote a library that can deal with this for JWT https://github.com/endiangroup/compandauth

The skiny is that you place a copy of some monotonic counter inside every JWT you issue, you keep track of the counter server side and compare with each request's JWT copy + some delta (which is the equivalent of maximum number of concurrent sessions you wish the user to have).


Set counter = 0 in DB. Put it into JWT. Increment the counter in DB to revoke the user. Compare counter in JWT < counter in DB. What's the problem?


then you're hitting the db on every request just to do auth.

if you _had_ to do that, I would put the counter into something like redis instead.


Don't you need to hit the DB anyway to fetch authorization data like user role? Clearly you aren't going to store it in JWT or you face the issue with invalidation. But fine, cache it in Redis. Problem solved.

10 timeout to reply. o_O


This conversation comes up all the time when discussing JWTs, and unfortunately I think the issue is usually way overblown:

1. I don't believe there are any real security issues regarding logout if JWTs have a sufficiently short expiration time.

2. The reason this issue comes up is because of compliance audits, who demand that as soon as the user logs out, that the supplied token becomes invalid. However, if the JWT is adequately discarded from the client, the fact that the JWT is still valid for another ~5-10 minutes or so is only a security risk if the token has already been stolen. The fact of the matter here is you really aren't protecting against a new attack vector with this "must immediately revoke tokens on logout" rule.

3. Despite my beliefs with #2 (and I'd love to hear an argument why this isn't valid), good luck trying to convince an auditor about that fact, who often love finding minor/mundane issues to justify their existence. So you'll still need to maintain a small blocklist, but the data in that list is usually very small (most users never log out these days) and can often be replicated in memory to each server.


I agree with your assessments, and your reply makes sense in the context of the above comments. Simply so that any readers arriving here that didn’t read the article arrive here, I just want to remind that these are not the fundamental complaints of the actual article itself, and are also unrelated to the proposed solution.


This is solved with a revocation list, which only needs to contain the tokens issued within the last ~5-10m for which there is a reason for revocation. Add to that a revocation list for access tokens, which are typically 24h.

The sum of both lists is vastly smaller and easier to manage than distributing session state and maintaining it server side for every single user.


I'm sure there are employees out there that have their self destruct scripts ready to go. If they are ever terminated they have 10 minutes of token validation time to blow everything up.


that would be insanely illegal.


I believe they are mentioning the fact that the server cannot unilaterally log the user out in a "naive" JWT-based implementation without storing and checking a token blocklist - which makes the session no longer stateless.


I can see that. I suppose when people say they need 'server-side session storage' I start thinking of app state, but in reality it could be as simple as storing a jwt refresh token that would be considered valid.


It matters in the context of folks that are trying to do a serverless architecture, sold on the idea that JWTs don’t require anything more than a function to issue auth


So you say it spreads like PHP?


And how, precisely, do you propose doing this convincing without popularizing the idea that it's a bad API?


Use the flaws to exploit an AWS, Azure or Google product?

And if you can't, are they really flaws? Or is this just an issue of some people implementing the standard badly, and they need to be taught to use better libraries?



I might slightly amend that to the less illegal "use the flaws to submit bugs to their bounty programs and get paid for your time".


You mean, like this? https://bhavukjain.com/blog/2020/05/30/zeroday-signin-with-a...

It's certainly possible to use JWT correctly, and with sufficient resources put towards auditing, most flaws will be caught. This doesn't make it a good design.


Sounds like trying to convince people to abandon IPv4 for IPv6. Even though IPv6 is a superior technology its still a tough sell. Arguments for doing nothing because change is hard make for bad technology considerations.

I am not stating any opinion upon JWT or alternatives.


JWTs are perfectly fine as a set of signed attributes if you are not using them for stateless session management (what big apps actually do this, in practice?). Most (if not all) popular JWT libraries reject "alg: none" at this point.

If JWTs don't match up with your use case, don't use it! Opaque, server bound tokens are fine in many cases.


You say that they reject alg: none, but even auth0 got caught by alg: nOnE…

One of the main issues I have with JWT is that it has a fairly high degree of cryptographic agility rather than a version number that specifies a set of cryptographic primitives.


> if you are not using them for stateless session management

REST APIs are required to be stateless, meaning the server does not store any state about the client session on the server-side. When you have multiple servers servicing requests there is no guarantee that subsequent requests will go to the same server. So having session state in memory won't work. There is nothing wrong in using JWT tokens with a REST service. In fact most services do just that.


> When you have multiple servers servicing requests there is no guarantee that subsequent requests will go to the same server.

Distributed key-value stores have been a thing for ages. Besides, the information you are accessing and manipulating through that REST API is probably stored in some sort of database, so you most likely already have a straightforward way to share state among your frontend servers. It's only a matter of whether it's fast enough for your purpose.

Most people don't even have to go "distributed" on the backend. A single Redis instance can handle upwards of 1 billion requests per day.


You are making my argument. You are saying there is no need for session state on frontend servers. That's my argument as well. And there's nothing wrong with JWT that prevents it from being used to identify the user or the associated backend data.


I think you are misunderstanding the statelessness of REST. Each HTTP request is stateless in the sense that it can be understood without having previous HTTP requests around. But you can build sessions on top of that (= into your application) and that is not "against the rules".

Also, with regarding to REST "front-end servers" aren't part of the discussion, but an implementation detail.


I am sorry, I don't agree with your interpretation.

My interpretation is aligned with this: https://www.ibm.com/docs/en/sdi/7.2.0.2?topic=reference-rest...

"...but creates no load and consumes no per-client storage on the set of servers or on the network"

So no, per-client session state would be against the principles of REST in my view.



I've worked on projects that used JWT to maintain session data and it's definitely a horrible idea. Halfway through the project it became very apparent that we were reinventing the wheel - having to solve problems that were never an issue with maintaining session data server side.

However, I currently use JWT for short term authorization tokens (5 minute expiration) between a web api and a websocket service. The service needs to be lightweight and not rely on database hits to confirm authorization.

But yeah, JWT gets misused VERY often.


As I understand it, it’s when people put the kitchen sink I to claims. Is that a fair single sentence description?

Aside, the idea you can set the entire JWT to “no security” from a signed packet and have a chance at a server accepting it, is crazy.


In our case we only pass a user id (which is public information anyway) and encrypt the token on top of that.

I think the encryption isn't necessary but hey why not.


I just want to point out that the article mentions the session issue upfront only to get it out of the way, and follows the session issue with its own set of interesting complaints.


Posted 4 years ago, and yet OIDC is still the closest thing we have to an auth standard.

Frankly, JWTs are very low on the “what’s broken” priority list.


Oh thank God. I was worried I was going to have to stop using the Java web toolkit.


JWT is widely deployed in a huge number of places and is a bit of a favourite in the banking industry at the moment. It's going to take a lot to displace it. It's also not solely used for session management (I've never used it for that).

Paseto looks fine, it avoids some of the pitfalls of weak algorithms etc, but that's not exactly tough to mitigate. They even say in the page that keeping a whitelist of algorithms is the approach most people take to JWT anyway. Could JWT be made stronger and more foolproof? No doubt, but I'm not sure that at this point the world is ready to move on, in fact we seem to be going gangbusters deploying and developing around it.

If PASETO is the future, perhaps the PASETO guys could talk to the OpenID folks and see if they can get some traction. But this is going to need to be led by the standards bodies and not by individual developers.


The arguments against JWTs always seem to boil down to them having too many sharp edges that are too easy to get wrong.

That is a good argument against things in isolation, but we're not working in isolation, we have classic old server-side sessions with cookies and session IDs and so on. Are JWTs better than those? Well... kinda?

Sessions are _hard_ to get right. Frameworks can do 80% of the work, but not everyone uses frameworks that handle them, and the last 20% is still hard. Then working in a multi-service environment that all gets much harder.

Could JWTs be improved? Maybe. Does that mean we should avoid them? Probably not, they solve a certain kind of problem better than the available alternatives, and rolling your own alternative is only one step away from rolling your own crypto.


Everything is a tool in a toolbox. JWTs are not a good replacement for sessions for a couple reasons -

    * You can't have decentralized authentication AND invalidate a token.
    * You have to have complicated client side logic (opposed to a cookie with a session id) to maintain your tokens. (Much of this is "solved" by using third party packages to handle it.)
To me, it's reinventing the wheel to use JWTs as long term mutable storage. JWTs are GREAT for short term authentication between decentralized systems.

I can use a screwdriver as a makeshift hammer, but should I?


Old article (2017) that misses the point of JWT entirely.


Please get back to me when you have a an implementation on the JVM that doesn't require libpaseto. The reason JWT is used everywhere is because it's usable on almost every stack you could possibly imagine. We all agree that JWT had some egregiously bad design decisions in the past that have all been papered over in most libraries.

Compared to XMLDSig, JWT is much better and XMLDSig has been widely deployed and used for almost 2 decades at this point, including some very high security applications.


A couple of past discussions:

Javascript Object Signing and Encryption is a Bad Standard (2017) - https://news.ycombinator.com/item?id=22364638 - Feb 2020 (55 comments)

JSON Web Tokens should be avoided - https://news.ycombinator.com/item?id=13865459 - March 2017 (297 comments)


Discussion from only a year ago:

https://news.ycombinator.com/item?id=22364638


or you could validate parameters from unauthenticated actors (like algorithm) and return an error if it does not match your expectations. you're allowed to reject a parameter if you don't support that parameter; looking at it and deciding that "alg: none" isn't acceptable counts as "understanding" a required header.


Once a week an article like this gets posted.


Yeah it's curious isn't it? Seems to get more attention than I understand.


anyone have secure battle tested tutorials how to done api auth without jwt?


I'd be wary of any tutorial that claims to be battle tested.


Print it out and use it in a rolled up paper fight?


I'm not sure what exactly do you want to learn but the most popular auth method for django rest framework is a token based auth, which differs from jwt. So maybe start there. And DRF as a lib is battle tested.


I think the real take away here is to choose the right tool for the job; and that even JWT is many times a good fit when used correctly.

And to be more objective while writing public blog posts.


>We're developing a simply secure alternative, called PASETO (Platform-Agnostic Security Tokens).

Of course. Because a new unproven, untested security standard will fix things ... and certainly doesn't introduce it's own set of issues and vulnerabilities (https://xkcd.com/927/)

The reality is that much of the problems with JWT came from misconfigured (or not configured) libraries. That's an issue for sure.

On the other hand JWT is used by EVERYONE so they are a known-factor and there's value in the fact that this standard has been battle-tested across many companies, and use-cases.


The Java Web Toolkit is a neat idea, but the licensing terms are a bit cumbersome.

Edit: The previous version of the title mentioned JWT.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: