With the traditional session system where only the session ID is stored on the client possibly even encrypted, the user won't be able to assume the identity of another user or escalate their privileges without accessing the database or the session store directly.
But with JWTs, it seems once the attacker gets a hold of the private signing key they can do huge amounts of damage. If we store user IDs in the JWT, couldn't they simply sign themselves a token for an arbitrary user and act on their behalf? Contrasting this to say an SSL certificate being stolen, which would allow MITM attacks this seems almost an order of magnitude worse. They would not even have to sniff any traffic or modify requests, they could just pick whichever user they want, and completely undetected access the system.
I do realize that private keys are meant to be private, and if I lose my SSH key and the attacker takes over my SSH key they can do whatever they want. But IIRC there have been many cases of SSL certificates being leaked (or stuff like Heartbleed), but that at least doesn't directly allow the user to assume arbitrary identity. With JWT it seems like we're putting everything into one basket and nothing happens to it.
Is this a real security concern? Are there ways of mitigating the issue, other than not using JWTs altogether? Or am I missing something?
I really like the idea of passing around a token with claims between services, but at the same time it feels a little like encrypting all your company's private data, posting it publically on reddit and thinking I hope they won't break the encryption.
The JWS signing key normally lives on the relatively trusted server (or third system)
this feels like a critical piece of information I didn't think of and it makes so much sense! I thought that an exploit in my app could leak my JWT token, but having a separate signing service with less attack surface area seems like a great solution at mitigating the threat.