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.
I have seen much discussion of the security of JSON Web Tokens -- replay, revocation, data transparency, token-specified alg, token encryption, XSS, CSRF -- but I've not seen any assessment of the risk imposed by relying on a signing key.
If someone breaches a server and acquires a JWT signing key, it seems to me that this person could thereafter use the key to forge unexpired JWTs and secretly gain access. Of course, a server could look up each JWT on each request to confirm its validity, but servers use JWTs exactly so they don't have to do this. The server could confirm the IP address, but that also involves a lookup if the JWT is not to be trusted, and apparently doing this precludes reliable mobile access anyway.
Contrast this with a breach of a server based on session IDs. If this server is hashing passwords, the attacker would have to snag and use a session ID separately for each user before it expires. If the server were only storing hashes of the session IDs, the attacker would have to write to the server to ensure access. Regardless, it seems that the attacker is less advantaged.
I have found one architecture that uses JWTs without this disadvantage. A reverse proxy sits between untrusted clients externally and a backend collection of microservices internally, described here by Nordic APIs. A client acquires an opaque token from an authorization server and uses that token to communicate with the server app for all requests. For each request, the proxy translates the opaque token into a JWT and caches their association. The external world never provides JWTs, limiting the damage wrought by stealing keys (because the proxy goes to the authentication server to confirm the opaque tokens). However, this approach requires dereferencing each client token just as session IDs require per-request dereferencing, eliminating the benefit of JWTs for client requests. In this case, JWTs just allow services to pass user data among themselves without having to fully trust one another -- but I'm still trying to understand the value of the approach.
My concern appears to apply only to the use of JWTs as authentication tokens by untrusted clients. Yet JWTs are used by a number of high-profile APIs, including Google APIs. What am I missing? Maybe server breaches are rarely read-only? Are there ways to mitigate the risk?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…