Given I created a custom JWT decoder as described in the Spring OAuth2 Resource Server Documentation with NimbusJwtDecoder.
Example:
@Bean
public JwtDecoder getJwtDecoder() throws ParseException {
NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder
.withJwkSetUri(this.properties.getJwkSetUri())
.jwsAlgorithms(algorithms -> {
algorithms.add(SignatureAlgorithm.ES256);
algorithms.add(SignatureAlgorithm.ES384);
algorithms.add(SignatureAlgorithm.ES512);
})
.build();
jwtDecoder.setJwtValidator(this.getTokenValidator());
return jwtDecoder
}
And I configure my Spring App as Oauth2 Resource Server, like:
@EnableWebSecurity
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain oauth2FilterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/api/v1/**").authenticated()
)
.oauth2ResourceServer(oauth2 -> oauth2
.jwt(Customizer.withDefaults()));
return http.build();
}
}
When I send a request to /api/v1/** with a JWT token that has a malformed JWT header
POST /api/v1/test HTTP/1.1
Host: localhost:80
Authorization: Bearer <MELFORMED_HEADER>.<PAYLOAD>.<SIGNATURE>
Expected Behavior
Then I expect that a 401 is responded with a www-authenticate header which doesn't expose any app internal information.
Something like:
www-authenticate: Bearer error="invalid_token", error_description="An error occurred while attempting to decode the Jwt: Invalid unsecured/JWS/JWE", error_uri="https://tools.ietf.org/html/rfc6750#section-3.1"
Current Behavior
Then currently a 401 is responded with a www-authenticate header which does expose that the app is using a Nimbusdecoder.
www-authenticate: Bearer error="invalid_token", error_description="An error occurred while attempting to decode the Jwt: Invalid unsecured/JWS/JWE header: Invalid JSON: com.nimbusds.jose.shaded.gson.stream.MalformedJsonException: Unterminated string at line 1 column 23 path $.", error_uri="https://tools.ietf.org/html/rfc6750#section-3.1"
Context How has this issue affected you? I am not sure if this is a security breach, but at least I expect, that my client is not bothered with server-internal information.
What are you trying to accomplish? Provide my clients with a clean API without exposing any server-internal details.
Comment From: jzheaux
Thanks, @akamom.
With other ParseExceptions in NimbusJwtDecoder, Spring Security drops Nimbus's error message and replaces it with "Malformed payload". I think it's a good idea to be consistent here and remove the information from the error message.
Are you able to submit a PR that catches the ParseException that JWTParser#parse throws and drop the Nimbus error message? You can see an example in the same file of what I'm talking about in NimbusJwtDecoder#processJwt:
catch (Exception ex) {
this.logger.trace(...)
if (ex.getCause() instanceof ParseException) {
throw new BadJwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, "Malformed payload"), ex);
}
throw new BadJwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, ex.getMessage()), ex);
}
If so, please base the PR off of 5.8.x, and once it's merged, I'll forward-port it to the other branches.
Comment From: madhu-kommula
Hello, We are facing the same issue with NimbusReactiveJwtDecoder. Can the same fix be applied to the reactive world as well?