I have not seen an authorization server that makes it easy to configure no signing algorithm or even one that might be considered insecure. Most of the client authentication providers I have used (I.e frameworks) have also forced a secure algorithm, usually starting with rsa 256. So while technically you can use a no algorithm signer, I have never seen this happen.
I would add two pros of jwts (I guess oauth 2 and oidc more specifically)
1. It standardizes your auth system. While sessions auth is mostly implemented in the same way across systems, learning oauth and oidc gives you a standard across the industry.
2. Jwts give an easy path to make “front end” applications and api authentication work in the same way. This in theory reduces your security surface area as all of your authnz code can be shared across your offerings.
If a short session time isnt good enough, you can use a simple key store to check for revoked tokens. Youll be hitting a db but its somewhat better since its just a very small db of revoked tokens.
Its hard for me to imagine though with like a 30 min or even few hour long token, under what circumstances you'd actually revoke tokens. If your db got leaked, you can rotate the key and invalidate all tokens. Otherwise, itd have to be something like you have some post login fraud detection in place. Cause jwt or not, if a user just signed in and a hacker got their auth token, what are you going to do? Sure you need to check the db to revoke it, but the problem is how would you know the tokens been compromised?
I wonder if an extension to the concept of jwt that extends the cryptographics chain down into some hardware component such as a TPM or secure enclave is the right answer. Basically the payload of the token could contain a pubkey for checking a signature on the request payload. The logout button would then have two local effects on the client side: delete the token and tell the hardware component to forget the private key.
Well, hence (functional). Making the client forget a token sounds trivial. But there's a long tail of clients out there, and many cases where things might get more complicated.
Maybe I'm damaged from working in a regulated industry, but a (possibly malicious) client who went through the logout process and could prove someone else reused the token after logout might have a case. Or another of a myriad of unknown possibilities.
It's all very unnecessary. There's a reason we all used to invalidate trust server side. It's just so much easier to reason about.
Why would you need to revoke on logout? Forgetting seems to be enough in all cases except maybe SSO revocation because in all other cases you can (and indeed often must) trust the client to protect the credential.
I think you need to take this a step further and really define your threat model instead of being despaired :)
If an attacker is able to steal a victim's cookie database, their system (or at the very least, their browser) is already deeply compromised. It is very likely that an attacker with such capabilities could prevent your website from ever sending the logout request (install a browser extension which blocks it, inject into the render process to silently drop it, modify the cached JavaScript on disk to inject code into the site, etc.). The logout functionality only works insofar as you trust the client, and in any circumstances where the client's cookies could be stolen you really can't trust the client. So logout revocation is not really a meaningful security boundary.
How about the scenario of a stolen device that's logged into the service. The victim logs in on another computer to try and reset their password and lock the thief out of the compromised account.
This is a different feature than a simple logout button though (something along the lines of "sign me out everywhere"), and many (smaller) websites don't actually support this. As far as I can tell, the very website we're on doesn't support it :) The parallel use case is SSO invalidation where you may need to immediately revoke access to a service after an employee is terminated.
You would need revocation in this case. Implementing this is easier when you already have database backed tokens, but unless you intend to support these features JWT is a totally reasonable engineering decision.
You have to store invalidated tokens anywhere they might pass through a service, which means you have to persist them for as long you can predict that there expiry will last. Simply putting them in a memory database isn't 100% if that db gets flushed, and then you might start storing them in a disk database, which at that point, you might as well have just read the db in the first place using cookie auth.
In microservices, you generally have to put an invalidated JWT cache between every service, or compromised JWT's are just floating around your intranet.
I've worked at a plethora of places who have JWT's who have no invalidation strategy what so ever, the majority of developers think that when you log out and the user has forgotten the JWT then you are all good......
You can do what Google and everyone else does, which is store the revoked tokens. At scale this is easy to do efficiently and rarely requires a network request since the number of revoked unexpired tokens is small.
You can use a separate DB that acts more like a cache for revocations- usually something where you can set a time to live on the row equal to the duration of the token itself.
That keeps your application DB free for application load, while keeping your identity validation logic nice and snappy.
Of course, adding infrastructure may be intimidating, but most applications that face any real load are going to be using redis or something similar anyway at some place in the stack.
The advantage of redis or similar kv DBs / caches comes in being lighter and faster than a full second database, mostly.
The secondary advantage is you don't need to deal with cookie storage, sticky sessions or anything else along those lines.
If you're manually hand crafting a server, go for it. If you're treating them like cattle not pets, going stateless with a bearer token tends to be easier.
I don't understand this argument against JWTs; if instantaneous session revocation is important for your use-case, versus JWTs more typical 5 minute or 60 minute expiration, there is nothing about JWTs which makes them poor candidates for going to the database as you would a session token. And, you get all the other benefits.
One example where this can matter: I've seen JWTs used in defense-in-depth scenarios where you've got an API gateway that does the initial JWT validation, including a round-trip to the database to check for revocation, but then had microservices behind the gateway only check the signature. Traditional session keys would require a database roundtrip for every validation, which could number in the dozens for a single API request.
Store reset_time per user. Use a message queue (or postgres notify) to push changes to this value to your apps. Check the user's token was created after the reset_time when validating it.
You would be required to keep a Map<UserId, Timestamp> in memory, potentially with TTL. Most systems can handle this easily for their expected user load. If not, you should have the engineering capacity to figure it out ;)
Logout button sets reset_time to now, as does revoking tokens. This would only allow you to revoke all tokens for one user at the same time, but this tends to be fine, since JWTs should be short-lived anyway and apps should deal with the expectation of them being expired/revoked.
Just populate the cache when you need it? You will need a database round trip for the first request per user per application restart, if they haven't reset since. I assumed this was obvious.
You'll want to store your user credentials that they traded for a JWT somewhere. The point of using JWTs is that most of your requests don't have to hit this database.
Yes, this is the trade off. If you are working in an industry where you need to be highly sensitive for data access even for short periods of times then oauth/oidc/jwts are probably not for you. If you really need an emergency escape hatch you can always rotate your singing keys and jwks and invalidate all of your tokens and force everyone to sign back in.
How do you find out a single token got leaked within the token lifetime? If it's that easy to detect a leaked token, why aren't you stopping the leak in the first place?
I think you're right, but it seems like you get into a tricky territory that'll never be great (as everything with security has compromised). Too long is an issue for attacks, but convenient for users. Too short and you have to do an initial re-auth over and over again, partially defeating the benefits.
Even if the TTL is short, there are plenty of ways to compromise a token and use it immediately in an automated system.
If you're using JWTs, I'd lean shorter TTLs and embrace this as a potential concern. Not sure what the best re-auth frequency is though. I'd be really interested to see other's thoughts on that.
But the token is used over SSL and the only way to get it afaik is to hijack the client device or somehow hijack the server. The first scenario is pretty rare and the second is pretty easy to avoid. I don’t think that’s really an edge case that’s concerning for 99% of applications.
Passwords being leaked is due to noobs and idiots in charge of systems, and probably not using an actual auth provider.
It really isn't that hard.
1. Send secure information over SSL. If some noob-tier dev decides that's too advanced for them, congrats I guess for being stupid.
2. Store passwords with hashing and salting. If you use an auth provider, like auth0 or firebase even, they will do this for you because they're not noobs. A noob-tier dev who stores plaintext passwords in a database with insecure connection and postgres:postgres is again stupid af.
Most of those leaked passwords are because of this. And don't think some Fortune 500 is not stupid. They outsource their development to Accenture or Detoilette, or any of the other outsourcers where they pay some "Software Architect" $8/hr to secure banking information (while charging the client $150/hr). I'm not throwing shade, but these companies are cheap af and throw bodies at the problem instead of experience and brains. I have direct experience with this, so I know how bad it is.
Don't confuse people being stupid (very common, 90% of any population) with a failure in a technology that others who don't understand it claim makes it inferior or something.
The internet and all the technology you use today is glued together by the <10% of people who actually understand computers, networking, and problem solving.
Just because a noob-dev uses session tokens doesn't mean it will be any secure if they fail those 2 points I mentioned. Those are so deadass simple to mitigate, anyone who purposefully skips on them should be named and shamed, and receive a 10 year cooldown from being a software developer.
I'd add that it's easier to abstract your software service from authentication. It's allowed me to write bridge signing from AzureAD, Okta etc, to a supported application deployed to differing environments on client hardware and readily integrating to different SSO systems.
I have been building this on and off for a number of years. Mostly focused on the document management side of things: https://github.com/bgroff/kala-app
For those that might not follow the link: “[ai code] is presumed to be tainted (i.e. of unclear copyright, not fitting NetBSD's licensing goals) and cannot be committed to NetBSD”.
So more of a provenance issue w.r.t licensing than an ideological one.
I thought it'd just be logistics. This is highly specialized OS code and I barely trust Copilot to do more than the most simple autocompletes. No way 99.9% of AI gen would pass a proper peer review.
Basically. The first part is creating a certificate request for a developer certificate, then apple creates a signing certificate for you. Then each executable part of your distribution needs to be signed with that signing certificate.
The second part is the notarization. This is where you upload a .zip, .pkg, or .dmg to apple and they build a hash of your distribution and serve that to folks through gatekeeper. You can also staple the notarization to the package and then you don’t need to talk to the apple servers.
This way apple can revoke your notarization and users will get warnings about your software being maleware.
Not the parent, but C# and Java are very similar in their feature set. One thing that I find interesting about the respective communities is, Java tends to develop JSR's where a standard is worked on by multiple vendors and published essentially as an interface. Many vendors then provide an implementation of the interface.
In C# Microsoft often provides the most popular tooling for common problems. For instance, in web development, Microsoft publishes ASP.net and Entity Framework. In Java there is Jax-rs (JSR 339) and JPA (JSR 317).
So depending on your preference for a strong centralized environment provided by a single vendor, or a decentralized standards based solution with many vendors, you might lean towards Java or C#.
Not disagreeing with your points. One thing mocks can be good at is to simulate errors that would be difficult to reproduce in an actual stack. For example, maybe you want to try and handle transient network issues or db connection failures, a mock could throw the correct exception easily, making your full stack do this would be challenging.
Cartobucket Auth is an OIDC/OAuth 2.1 system that is meant to be easy to extend and embed into your existing infrastructure. To that end, if you are using Java, you can use the built in auth-data package, you can also use the generated SDK's for the API. Cartobucket Auth is also built to be extended or parts replaced using the Quarkus DI system easily, should you need the system to do something else that is specific to your application.