2

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.

Joe Lapp
  • 157
  • 5
  • I posted my first formulation of this question on Stackoverflow but was advised to post here. Older discussion at http://stackoverflow.com/questions/37495362/are-breaches-of-jwt-based-servers-more-damaging – Joe Lapp Jun 05 '16 at 00:26
  • For a discussion of securing JWT signing keys, see: http://security.stackexchange.com/questions/87130/json-web-tokens-how-to-securely-store-the-key – Joe Lapp Jun 05 '16 at 00:27
  • I've also thought of a way to provide additional security by having private keys only ever stored in RAM, even when load-balancing across multiple servers, but that's still less warm-and-fuzzy than confirming each request against a DB; and it's an aside to the question I'm asking, anyway. – Joe Lapp Jun 05 '16 at 00:35
  • I've seen the assertion that JWTs provide an "additional layer" of security. The server checks the JWT payload against the information retrieved from looking up the token. But 1st, the JWT signature doesn't help in this case, and 2nd, you can also increase the amount of data that the attacker must properly guess just by extending the length of the session random. So I'm still left wondering how JWTs improve things. – Joe Lapp Jun 05 '16 at 18:09
  • "the signing key must reside somewhere unhashed" ... have you ever heard of an HSM ? That's what real people who are serious about their security use to protect their keys. – Little Code Jun 05 '16 at 20:31
  • This article points out that all these problems and more plague API keys. There's no session random alternative to API keys, so every API service and API client deals with this problem irrespective of JWTs. It seems that we face the problem no matter what. https://blog.cloudsecurityalliance.org/2011/04/18/protect-the-api-keys-to-your-cloud-kingdom/ – Joe Lapp Jun 05 '16 at 21:30
  • (consolidating) So the only use of JWTs that's more secure than session randoms requires cryptographic hardware? That could be the answer to my question. I haven't seen it stated before. HSM is hard to come by for cloud solutions. Linode does not offer HSM. Rackspace has only just started an "early access program" for HSM. Amazon Web Services provides HSM to VPN customers. – Joe Lapp Jun 05 '16 at 23:36
  • "HSM is hard to come by for cloud solutions" ? Really. There's this little cloud company you may have never heard of called Microsoft who run something called Azure. I suggest you spend a little time on their website, you may be pleasantly surprised. ;-) – Little Code Jun 06 '16 at 08:51

2 Answers2

2

You've already mentioned the stateless federated benefits of JWTs, I'm sure those can be agreed on.

An attacker doesn't need a user's password to access protected resources, just access to their authentication context.

I think one of the risks that you're missing with sever-side tokens, or session based methods, is that those identifiers are also stored on the server. In fact they're often stored in places that are more frequently compromised read-only than the filesystem (where private keys are most often stored), the database. Once an attacker has a session ID or auth token then they have the same capacity to access relying parties as they do with a JWT.

Another weak link in the chain is user-side storage, which is often an easier compromise in a targeted attack than the server. This risk can be mitigated somewhat by frequently cycling tokens; a core feature of well-implemented JWT systems, but not frequently done with long-lived session tokens in practice.

joshperry
  • 361
  • 1
  • 8
  • Thanks for responding. Can you spell out the benefits of federated use? (Or point me to something?) I'm not sure I'm seeing them. – Joe Lapp Jun 05 '16 at 12:30
  • 1
    Also, the tokens can be stored server-side in hashed form -- they need not be emitted again, so servers can protect them. I agree that the client is the weak link, but exposure at a client compromises only that client, not all clients and all users. I'm still seeing a huge difference in security between relying on JWT signatures and old-style session randoms. – Joe Lapp Jun 05 '16 at 12:33
  • 1
    FWIW, I agree with you, @JoeLapp; the single-point-of-failure of a JWT signing key, the difficulty of protecting the key adequately, and the triviality of forging tokens for arbitrary users once the key is compromised all are serious risks to JWT security and mean that a JWT-based system is (all else being equal) less secure than a well-implemented system using random session tokens. Of course, most random-token systems are less secure than they could be, for example they rarely use hashing to store the session token, and may even be vulnerable to a timing attack on the token verification. – CBHacking May 06 '17 at 21:46
  • 2
    You can also make JWT's more secure by doing things like using a HSM to store the key (though this is pricey to distribute), or at least using a privileged process (which the server talks to via some IPC mechanism) to sign and verify JWTs; then the server can't actually read the key. You can also frequently rotate keys, overlapping an old and a new key and allowing JWTs signed by either but replacing old-key signatures with new ones; this severely reduces the max lifetime of an inactive session (which sometimes is problematic) but also makes one-time key theft much less harmful. – CBHacking May 06 '17 at 21:52
  • @JoeLapp: I have two questions: 1) If privateKey is leaked, how are all users at risk? I understand that the same privateKey is used to sign all users JWT, but how would the attacker know the "userIds" of all users if they know the privateKey? 2) If the attacker gets access to the DB (in case you're also considering this), then it does not matter which auth method one uses, so why JWT is particularly bad? – Nawaz May 22 '22 at 10:21
0

There is a great write-up about JWTs used for session management by Sven Slootweg. Towards the end article also mentions some use-cases where you may benefit from JWTs.

Particularly, he talks about single-use authorization needs. The example is a download server, which accepts JWTs to authorize file access. The download server itself can be kept stateless as the JWT has all the information required to authenticate and authorize the clients.

Daniel Szpisjak
  • 1,825
  • 10
  • 19