spring-attic / spring-security-oauth

Support for adding OAuth1(a) and OAuth2 features (consumer and provider) for Spring web applications.
http://github.com/spring-projects/spring-security-oauth
Apache License 2.0
4.7k stars 4.04k forks source link

JWT.header(token) fail to parse fields containing ":" #1572

Open Bair95 opened 5 years ago

Bair95 commented 5 years ago

Summary

When receiving an Oauth2 JWT token and parsing the additionalIformations (idToken), JwtHelper.header(idToken) fail to parse fields containing ":".

Actual Behavior

The field "kid" containing "public:uuid-number-random" is parsed and the resulting value is only "public".

Expected Behavior

The resulting value should be "public:uuid-number-random"

Configuration

Java 8 Linux Manjaro

Version

Spring-security-jwt 1.0.9.RELEASE Spring-security-jwt 1.0.10.RELEASE

Sample

Test Example JWtHelper from spring-security vs nimbusd jwt

@Test
public void whenParsingTokenSemiColonFieldAreTruncated() throws ParseException {
    String idToken = "eyJhbGciOiJSUzI1NiIsImtpZCI6InB1YmxpYzozNTJkMTA3MS1kZDlmLTQ0NjQtYTYzZi03NjFlYjllY2U2N2YiLCJ0eXAiOiJKV1QifQ.eyJhdF9oYXNoIjoiVXhjWjFuYnFaQ2ExSGdGc0ZJZXlhUSIsImF1ZCI6WyJhdXRoLWNvZGUtY2xpZW50Il0sImF1dGhfdGltZSI6MTU0OTEwNjg4NiwiZXhwIjoxNTQ5MTEwNDg2LCJpYXQiOjE1NDkxMDY4ODYsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6NDQ0NC8iLCJqdGkiOiJiZjQ4NjA5Ni00ZjMzLTQ2NTMtODMxZS0zNTVhMDIwODEyYjEiLCJub25jZSI6IiIsInJhdCI6MTU0OTEwNjg4Miwic3ViIjoiZm9vQGJhci5jb20ifQ.QyTx8Fd8HD1RA6YxyugHvoCxsMluaeu6O9gWQCpJh9xqRRpE6slYFe9XKv95maTXQSmem_SVepyrcopvvNkHJYf_qaoIlnH_Ljp-1YLyOp_ToDglkk40Nkpq37y3vEkNY_pL5YFdKsKd1-9YXfu0fcdxfLJCjsaLXF1l-rshspmmYIB_n4CvIgJUk3FxHabX6061R0a94YmXDG1JpKhO3dptG5vofQ4DtGX_t7a5RDwmzkaxZ6FTV_DeNuDpvHzp44_LfEmq_kwSeapJb-MsD6JCEIRqQiuYWJ5LY6pcTZywl4MOoDJDcYZ7Kc0ihAS6Jkd8OTSqTL_GcZ3DN9dlhnYwlJsZKKUMg_8uPxB3nI4g8-MI8GnHIq9oPxzhw4Ht5LSm-3k8nNQzHHCcjM9pUfMyA5Lk2tKAIlHYO8HmA8ZMwG1r9miVhK38sb0zpRAYXyLP4NelgloenOMIh-PWRS4-AZ5ZhDNrv9vO6_IEvvtaiTo_UPtDFRVxc2hUjCkUysKbtH-UM3SM6EF7nd0auXoECrbpSPD9E-JR3CoNQv44721nxuzjZSCaDpV-UIB-20pSMJA5j-AzwEInf8GRcIBlH-IG8GreEiZM4p_Mx9wapiV7n9ZI5kY6HzSqrRZCVLF-wpiQr9ofQTIVIixN8PpcXRBiXfA8a0YGHsGKWHs";
    Map<String, Object> additionalInformations = new HashMap<>();
    additionalInformations.put("id_token",idToken);
    DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken(TOKEN);
    token.setAdditionalInformation(additionalInformations);
    String decodedIdToken = token.getAdditionalInformation().get("id_token").toString();
    Map<String, String> headers = JwtHelper.headers(decodedIdToken);
    System.out.println(headers.values());
    System.out.println(headers.get("kid"));

    System.out.println(JWTParser.parse(idToken).getHeader().toString());
    System.out.println(JWTParser.parse(idToken).getHeader().toJSONObject().get("kid"));
}

}

Bair95 commented 5 years ago

In spring-security-jwt submodule, Class JwtTests; This edited test should'nt pass as "foo" value is "bar:barbarbar". But only bar is parsed so the test is still passing. @Test public void inspectCustomHeaders() throws Exception { Map<String, String> headers = JwtHelper.headers( JwtHelper.encode(JOE_CLAIM_SEGMENT, hmac, Collections.singletonMap("foo", "bar:barbarbar")).getEncoded()); assertEquals("Wrong header: " + headers, "bar", headers.get("foo")); assertEquals("Wrong header: " + headers, "HS256", headers.get("alg")); assertEquals("Wrong header: " + headers, "JWT", headers.get("typ")); }

I'm not sure why the module is commented in the pom, nor why I can't find any dedicated repository for spring-security-jwt.

Bair95 commented 5 years ago

the error comes from JwtHelper.parseMapInternal, this line is responsible of the bad parsing: String[] values = pair.split(":"); I can't see any reason why a JSON parser is manually reimplemented here instead of using a battle tested library (GSON,Json, you name it) that would prevent this kind of obvious and avoidable bug.