auth0 / java-jwt

Java implementation of JSON Web Token (JWT)
MIT License
5.85k stars 922 forks source link

Vulnerability fix #53

Closed camilow closed 8 years ago

camilow commented 8 years ago

Addressing the serious vulnerability well described here: https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/ All that is needed is a way to force the use of the intended algorithm.

In the verification code, just replace this String algorithm = getAlgorithm(jwtHeader); With this: String algorithm = givenAlgorithm != null ? givenAlgorithm : getAlgorithm(jwtHeader); and add a parameter to the method (... String givenAlgorithm )

You could even clone the old method to call this new method to preserver backward compatibility.

Enhancement - any way to make the parameter of class Algorithm instead of String?

Works like a charm.

Sorry, not familiar enough with github to make the changes myself (:

Great library!

richardhuaaa commented 8 years ago

I emailed whitehat@auth0.zendesk.com, and it seems like the vulnerability is actually covered (albeit indirectly). In my opinion this issue can be closed. Here is how they explained it:


Even though we don't explicitly whitelist the algorithms the JWTVerifier should use, we are doing so by means of how you create an instance of that class.

If you need to validate HS signed tokens you will use one of the following:

public JWTVerifier(final String secret, final String audience, final String issuer) { }
public JWTVerifier(final String secret, final String audience) {}
public JWTVerifier(final String secret) {}
public JWTVerifier(final byte[] secret, final String audience) {}
public JWTVerifier(final byte[] secret) {}
public JWTVerifier(final byte[] secret, final String audience, final String issuer) {}

and if you want to validate using RS:

public JWTVerifier(final PublicKey publicKey, final String audience, final String issuer) {}
public JWTVerifier(final PublicKey publicKey, final String audience) {}
public JWTVerifier(final PublicKey publicKey) {}

Internally they store either a secret or publicKey properties and before validating the token they check that the one to be used for is non-null. For RS it checks here the publicKey and for HS the check for the secret is here, raising an exception in both cases if the value is null.

So if you expect RS signed tokens and you supply one signed with HS using the public key it will fail since the verifier has no secret configured, only a public key (the same applies when expecting HS tokens and you got a RS one). Also we are not allowing the none algorithm so that covers the vulnerabilities specified in the blog post.

We are planning on reworking this lib to make it explicit to whitelist the algorithms that the JWTVerifier should use.