UPDATE: I have concluded my research on this problem and posted a lengthy blog entry explaining my findings: The Unspoken Vulnerability of JWTs. I explain how the big push to use JWTs for local authentication is leaving out one crucial detail: that the signing key must be protected. I also explain that unless you're willing to go to great lengths to protect the keys, you're better off either delegating authentication via Oauth or using traditional session IDs.
(This post has been enduring an up-vote/down-vote battle and has been as low as -2. I used to be paid to evaluate systems for their security, so please try not to dismiss this investigation and the above-linked conclusions out-of-hand.)
I'm seeing blog after blog and book after book tout JSON Web Tokens (JWTs) as a means for highly scalable APIs that don't have to hit the database to authorize each request. I know that confirming a signature spares a database lookup, but it also seems to me that this approach puts servers at much greater risk of exploitation.
Consider the scenario in which an attacker breaks into a server and acquires read access to the entire file system, including any databases. Also assume that the intrusion goes undetected for a time.
A traditional solution will store hashes of passwords and hashes of session IDs, leaving the attacker still unable to exploit the application through its interfaces. On the other hand, if the server issues signed JWTs for downstream authorization, the signing key must reside somewhere unhashed. If the attacker locates it, the attacker can thereafter forge unexpired JWT tokens to access downstream servers unnoticed. (The attacker could be detected by doing lookups to confirm the client, but that would defeat the purpose of using JWT signatures for scalable authorization.)
Server breaches do happen. Generally, accounts can read more than they can write, so it seems reasonable to assume that most breaches are read-only. When they happen, companies are proud when they can declare that impact was minimal by virtue of storing hashed values rather than plaintext. Unfortunately, under JWT-based authorization, the company would have to say that yes, they do hash passwords, but all accounts were compromized anyway. (Sessions are usually less of an issue because of their shorter durations.)
I understand that there are many legitimate uses of keys, that there are a number of approaches to protecting keys, and that there are usually serious consequences to keys being stolen. However, in this case people are proposing replacing an older authorization mechanism with a newer, less-secure one. That is what doesn't make sense to me.
And yet many smart people have put much effort into JWT signing standards and implementations. The existence of the Oauth token introspection protocol is further evidence to me that secure systems would not rely on the token alone for authorization. So what are real benefits of signed JWTs? What are JWT signatures really intended for?
Here are the seemingly more-legitimate uses that I'm aware of:
- Signing with a server-wide secret allows for minimizing the impact of DoS attacks, because requests can generally be stopped before hitting the database.
- To validate JWT payload data that requires only an intermediate level of security. (I have a hard time imagining such data.)
- To allow untrusted microservices to efficiently share authorization information acquired from a commonly trusted authentication service. See the description at Nordic APIs. (But I'm still trying to appreciate the benefit.)
I thought of the first of these myself, though it's likely others have too. I have trouble understanding the other uses. I have not yet seen a clear, convincing explanation of why anyone is signing JWTs.
What's the real scoop? Thanks for your help!
(Context for the question: I'm trying to decide whether to abandon the idea of gaining scalability through signature-based authorization.)
P.S. I've seen JWT signatures described as an alternative "authentication" scheme. I'm pretty sure authentication occurs at token acquisition and thereafter it's only authorization. Please correct me if I'm wrong.