From 26cab6beee20bff5e183e313130f74af017a1f76 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 20 May 2026 17:33:06 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[CRITICAL]?= =?UTF-8?q?=20Restrict=20ast.Call=20in=20type=20string=20evaluation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed a vulnerability in `src/codeweaver/core/di/container.py` where the AST validator for type string evaluation allowed generic `ast.Call` nodes. This permitted arbitrary code execution during the subsequent `eval()` call if an attacker supplied a malicious string executing available functions in the environment (e.g., `os.system`). The fix restricts `ast.Call` nodes exclusively to the `Depends` function. Also updated `.jules/sentinel.md` with learnings on this vulnerability. Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --- .jules/sentinel.md | 5 +++++ src/codeweaver/core/di/container.py | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/.jules/sentinel.md b/.jules/sentinel.md index 1959a5253..482204880 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -4,3 +4,8 @@ **Vulnerability:** Found an unused `_attempt_import` function in `src/codeweaver/server/mcp/server.py` that dynamically imports a module directly from unvalidated configuration (`import_module(mw.rsplit(".", 1)[0])`), leading to potential arbitrary code execution. **Learning:** Functions that perform dynamic imports should not be left around in the codebase if they are unused, especially if they are designed to take unvalidated strings as input. **Prevention:** Avoid dynamic imports based on configuration or inputs without strict whitelisting. Use tools like `semgrep` with python security rules to actively catch these patterns. + +## 2026-04-21 - Arbitrary code execution via ast.Call in type string evaluation +**Vulnerability:** Found that `_safe_eval_type` in `src/codeweaver/core/di/container.py` used an AST validator that allowed `ast.Call` nodes to execute any available callable in the evaluation namespace. By crafting a type annotation string like `"os.system('echo pwned')"` (provided `os` is injected or imported), an attacker could achieve arbitrary code execution because the validated string was subsequently evaluated with `eval()`. +**Learning:** Even when AST validation correctly rejects `__` dunder accesses and restricts allowed node types, allowing generic `ast.Call` nodes remains dangerous if the execution environment contains potent functions or objects. Whitelisting specific functions (like `Depends`) inside the `ast.Call` validator is required to prevent bypasses. +**Prevention:** Explicitly restrict function calls (`ast.Call`) in custom `eval` AST validators to only known, safe operations. Ensure any code dynamically evaluating parsed input never permits generic execution. diff --git a/src/codeweaver/core/di/container.py b/src/codeweaver/core/di/container.py index 7cd68ce98..57d194331 100644 --- a/src/codeweaver/core/di/container.py +++ b/src/codeweaver/core/di/container.py @@ -136,6 +136,12 @@ def generic_visit(self, node: ast.AST) -> None: if isinstance(node, ast.Attribute) and node.attr.startswith("__"): raise TypeError(f"Forbidden dunder attribute: {node.attr}") + # Security: Restrict calls to prevent arbitrary code execution during type evaluation + if isinstance(node, ast.Call) and ( + not isinstance(node.func, ast.Name) or node.func.id != "Depends" + ): + raise TypeError("Forbidden call type: only Depends() is allowed") + super().generic_visit(node) try: