GHSA-vwf3-4xxj-qg6h: mcp-contextforge-gateway has Server-Side Template Injection (SSTI) leading to Remote Code Execution in `PromptService._render_template` via unsandboxed Jinja2 Environment
Summary
mcpgateway.services.prompt_service.PromptService renders user-supplied prompt templates using Jinja2's plain Environment() rather than SandboxedEnvironment. An authenticated user with permission to register or update prompt templates can store a malicious template that, on subsequent rendering, executes arbitrary Python code on the gateway host with the privileges of the gateway process. This is a Server-Side Template Injection (SSTI) vulnerability leading to Remote Code Execution.
Details
Affected component: mcpgateway/services/prompt_service.py
Affected version: 0.9.0 (verified). The fix in the unreleased main branch indicates all earlier published versions are likewise affected.
Vulnerable code
mcpgateway/services/prompt_service.py, line 26:
from jinja2 import Environment, meta, select_autoescape
mcpgateway/services/prompt_service.py, line 135 (inside PromptService.init):
self._jinja_env = Environment(
autoescape=select_autoescape(["html", "xml"]),
trim_blocks=True,
lstrip_blocks=True,
)
mcpgateway/services/prompt_service.py, lines 1592–1616 (_render_template):
def _render_template(self, template: str, arguments: Dict[str, str]) -> str:
...
try:
jinja_template = self._jinja_env.from_string(template)
return jinja_template.render(arguments)
except Exception:
try:
return template.format(arguments)
except Exception as e:
raise PromptError(f"Failed to render template: {str(e)}")
_render_template is invoked from PromptService.get_prompt (line 892):
rendered = self._render_template(prompt.template, arguments)
Where prompt.template is loaded from the database. The template field of the database row is populated via the register_prompt, update_prompt, and register_prompts_bulk API endpoints, which accept attacker-controlled template content from authenticated API callers.
Because self._jinja_env is a plain jinja2.Environment rather than jinja2.sandbox.SandboxedEnvironment, Jinja2 imposes no restrictions on attribute traversal, function calls, or buil
Details
Original advisory: https://github.com/advisories/GHSA-vwf3-4xxj-qg6h
More from GitHub Security Advisories
- mediumGHSA-p43p-whwx-q52h: JupyterHub has Unauthenticated Denial of Service via Unbounded Username Logging on Failed…2026-08-25
- highGHSA-cv84-9p8j-fj68: icalendar has Algorithmic Complexity in Equality2026-08-25
- highGHSA-hvfh-5mj3-5f3j: Chainlist has SSRF via MCP SSE and streamable-http transports that allows unauthenticated…2026-08-25
- criticalGHSA-w3fx-mc44-mf6j: Chainlit has command injection via MCP stdio transport that allows unauthenticated remote…2026-08-25
- mediumGHSA-72f3-6w86-7rv3: @arikusi/deepseek-mcp-server: Missing Authentication on Self-Hosted HTTP MCP Endpoint2026-08-25