🛡️ Sentinel: [CRITICAL] Fix arbitrary code execution vulnerability in container type resolution#376
Conversation
… container type resolution Added a strict whitelist for `ast.Call` nodes parsed inside `_safe_eval_type` before passing strings to `eval()` to prevent Arbitrary Code Execution (ACE) vulnerabilities. Modified `TypeValidator.generic_visit` to intercept `ast.Call` nodes and assert they map strictly to allowed known typing definitions (like `Depends`, `depends`, `Field`, `Parameter`, etc.), raising a TypeError for any unsupported function calls (e.g. system commands). Checked code with format, linting, and tests to ensure correctness. Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
Reviewer's GuideTightens security of the _safe_eval_type AST validator in the DI container by whitelisting allowed function calls in type strings and documents the vulnerability and mitigation in the Sentinel security log. Flow diagram for updated _safe_eval_type AST validationflowchart TD
A[type_str input] --> B[ast.parse]
B --> C[SafeNodeVisitor.visit]
C --> D{node is ast.Call?}
D -- No --> G[Continue AST validation]
D -- Yes --> E[Extract func_name from ast.Name or ast.Attribute]
E --> F{func_name in allowed_funcs?}
F -- No --> H[raise TypeError]
F -- Yes --> G
G --> I[eval compiled AST in restricted globalns]
I --> J[Return evaluated type or None]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
🤖 Hi @bashandbone, I've received your request, and I'm working on it now! You can track my progress in the logs for more details. |
|
🤖 I'm sorry @bashandbone, but I was unable to process your request. Please see the logs for more details. |
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- The
ast.Callhandling currently treats any attribute call as allowed if the attribute name matches (e.g.,os.Depends), so you may want to also validate the full dotted path or restrict calls to bare names only to avoid bypass via arbitrary modules. - Consider extracting the
allowed_funcsset to a module- or class-level constant so that the whitelist is easier to audit and update in one place, rather than being embedded inside the visitor method.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The `ast.Call` handling currently treats any attribute call as allowed if the attribute name matches (e.g., `os.Depends`), so you may want to also validate the full dotted path or restrict calls to bare names only to avoid bypass via arbitrary modules.
- Consider extracting the `allowed_funcs` set to a module- or class-level constant so that the whitelist is easier to audit and update in one place, rather than being embedded inside the visitor method.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Pull request overview
This PR aims to harden the DI container’s string-based type annotation evaluation to prevent arbitrary code execution by restricting which ast.Call nodes are permitted during _safe_eval_type().
Changes:
- Added a function-name whitelist for
ast.Callnodes during type-string AST validation inContainer._safe_eval_type. - Documented the vulnerability and mitigation approach in the Jules sentinel security notes.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/codeweaver/core/di/container.py |
Restricts which function calls are allowed when validating/evaluating string type annotations. |
.jules/sentinel.md |
Adds a security incident note describing the ACE risk and mitigation strategy. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Security: Restrict arbitrary function execution in evaluate | ||
| if isinstance(node, ast.Call): | ||
| func_name = None | ||
| if isinstance(node.func, ast.Name): | ||
| func_name = node.func.id | ||
| elif isinstance(node.func, ast.Attribute): | ||
| func_name = node.func.attr | ||
|
|
||
| allowed_funcs = { | ||
| "Depends", | ||
| "depends", | ||
| "Field", | ||
| "PrivateAttr", | ||
| "Tag", | ||
| "Parameter", | ||
| "AfterValidator", | ||
| "BeforeValidator", | ||
| "Discriminator", | ||
| "GetPydanticSchema", | ||
| "uuid7", | ||
| } | ||
| if func_name not in allowed_funcs: | ||
| raise TypeError(f"Arbitrary function calls are forbidden: {func_name}") | ||
|
|
| allowed_funcs = { | ||
| "Depends", | ||
| "depends", | ||
| "Field", | ||
| "PrivateAttr", |
🚨 Severity: CRITICAL
💡 Vulnerability: Unconstrained
ast.Callnodes were allowed when evaluating string type annotations in_safe_eval_typeinsidesrc/codeweaver/core/di/container.py, allowing the execution of any functions available in the evaluated global scope.🎯 Impact: If
_safe_eval_typeparses untrusted or dynamically resolved string contents into an AST tree and then runseval(), an attacker could inject Python arbitrary code execution commands (such asos.system) directly into the evaluation block.🔧 Fix: Introduced an exact name matcher for function calls mapped against a hardcoded whitelist composed entirely of safe internal and third-party typing/dependency tools like
Depends,Field,GetPydanticSchema, andParameter.✅ Verification: Verified by testing explicitly unmapped function nodes (like
os.system) locally during discovery which resulted in the properTypeErrorblocking their dispatch intoeval(). Runningmise //:test tests/unit/core/ensures this strict implementation doesn't break pre-existing dependency injections in the tree.PR created automatically by Jules for task 12687173228044087168 started by @bashandbone
Summary by Sourcery
Harden type string evaluation in the DI container to prevent arbitrary code execution during container type resolution.
Bug Fixes:
_safe_eval_typeby only allowing a small, explicit whitelist of safe callables in ASTCallnodes during type evaluation.Documentation: