GHSA-5f29-2333-h9c7 OpenMetadata's Server-Side Template Injection (SSTI) in FreeMarker email templates leads to RCE
OpenMetadata RCE Vulnerability - Proof of ConceptExecutive Summary**CRITICAL Remote Code Execution vulnerability** confirmed in OpenMetadata v1.11.2 via **Server-Side Template Injection (SSTI)** in FreeMarker email templates.Credit@lnlinh31, @satthusaosan, @TheMacCuoi, @get-wright, @Ohnooo1234, @hienduc14 – FPT Cloud AppSec Research Team, FPT Smart CloudVulnerability Details1. Root CauseFile: `openmetadata-service/src/main/java/org/openmetadata/service/util/DefaultTemplateProvider.java`**Lines 35-45** contain unsafe FreeMarker template instantiation:**Missing Security Controls**:❌ No `setNewBuiltinClassResolver(TemplateClassResolver.SAFER_RESOLVER)` - Allows arbitrary class instantiation❌ No `setAPIBuiltinEnabled(false)` - Enables `?api` built-in for reflection❌ No input validation - Template content not sanitized2. Attack Vector (VERIFIED)**Step 1**: Attacker with Admin role modifies EmailTemplate via PATCH endpoint**Step 2**: Malicious template stored in MySQL database:**Step 3**: Trigger template rendering via email notification:Password changeUser invitationAccount activity notificationTest email (if SMTP configured)**Step 4**: RCE execution in `DefaultTemplateProvider.getTemplate()`:Exploit VerificationEnvironment**Version**: OpenMetadata 1.11.2 (Latest)**Platform**: Docker Compose (MySQL 8.0 + Elasticsearch 8.11.4)**Test Date**: December 15, 2025Step-by-Step Reproduction1. Deploy OpenMetadata 1.11.2**Result**: ✅ OpenMetadata running on localhost:85852. Obtain Admin JWT Token**Result**: ✅ Token obtained (654 characters, 1-hour expiry)3. Identify Target Template**Result**: ✅ Template ID: `855f58c6-1b80-467a-b92e-71c425e9bfdb`4. Inject RCE Payload**Result**: ✅ **HTTP 200 OK** - Template modified successfully**Response Excerpt**:5. Setup SMTP Server**Result**: ✅ SMTP server ready at fakesmtp:10256. Trigger RCE Execution**Result**: ✅ **HTTP 200 OK** - "Test Email Sent Successfully."7. Verify RCE Execution**Result**: ✅ **RCE CONFIRMED!****Email Content**:**Command Execution Proof**:✅ `whoami` command executed → returned `openmetadata`✅ `pwd` command executed → returned `/opt/openmetadata`✅ Commands ran as server process user✅ Full arbitrary command execution achievedAttack ScenariosScenario 1: Privilege EscalationAttacker compromises Admin account (phishing, credential stuffing, etc.)Injects RCE payload into `password-reset` templateTriggers password reset for target userRCE executes as OpenMetadata server user during email renderingAttacker gains shell access to application serverScenario 2: Data ExfiltrationExfiltrates environment variables containing:Database credentialsAPI keys and secretsJWT signing keysCloud provider credentialsScenario 3: Reverse ShellEstablishes persistent access for:Interactive command executionLateral movement to connected systemsDatabase direct accessKubernetes cluster compromise (if containerized)Impact AssessmentTechnical Impact**Confidentiality**: **HIGH** - Access to database credentials, API keys, secrets**Integrity**: **HIGH** - Full control over OpenMetadata application and data**Availability**: **HIGH** - Ability to crash application, delete data, deny serviceBusiness Impact**Data Breach**: Access to all metadata including sensitive schema information, PII mappings, data lineage**Compliance**: GDPR, SOC2, HIPAA violations if exploited**Reputation**: Critical security failure in data governance platform**Supply Chain**: Potential pivot to connected data sources (70+ connectors)CVSS 3.1 Score**Attack Vector (AV)**: Network (N)**Attack Complexity (AC)**: Low (L) - Simple API requests**Privileges Required (PR)**: High (H) - Admin role required**User Interaction (UI)**: None (N)**Scope (S)**: Changed (C) - Impacts beyond application (server OS)**Confidentiality (C)**: High (H)**Integrity (I)**: High (H)**Availability (A)**: High (H)**Score**: **9.1 (CRITICAL)**RemediationImmediate Fix (CRITICAL)**File**: `openmetadata-service/src/main/java/org/openmetadata/service/util/DefaultTemplateProvider.java`**Replace lines 38-42 with:**
CVSS v4.0 score: 8.5
CVSS v3.1 score: 9.1