🛡️ Sentinel: [CRITICAL] Fix ACE vulnerability in safe type evaluation#366
🛡️ Sentinel: [CRITICAL] Fix ACE vulnerability in safe type evaluation#366bashandbone wants to merge 1 commit into
Conversation
- Identified that `_safe_eval_type` in `src/codeweaver/core/di/container.py` allowed generic `ast.Call` nodes. - Fixed the Arbitrary Code Execution (ACE) vulnerability by verifying the `ast.Call` function names against a strict whitelist. - Updated `.jules/sentinel.md` journal with critical learnings. - Ensured formatting passes and tests successfully verify the fix. 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 the container’s Flow diagram for _safe_eval_type ast.Call whitelist validationflowchart LR
A[type_str AST parsed] --> B[AstValidator.generic_visit node]
B --> C{node is ast.Call?}
C -- No --> D[super.generic_visit node]
C -- Yes --> E{node.func is ast.Name?}
E -- Yes --> F[func_name = node.func.id]
E -- No --> G{node.func is ast.Attribute?}
G -- Yes --> H[func_name = node.func.attr]
G -- No --> I[raise TypeError Forbidden call representation]
F --> J{func_name in whitelist?
Depends
depends
Field
PrivateAttr
Tag}
H --> J
J -- No --> K[raise TypeError Forbidden callable in type string]
J -- Yes --> D
D --> L[eval type_str with validated AST]
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:
- Consider extracting the hard-coded callable whitelist (
{"Depends", "depends", "Field", "PrivateAttr", "Tag"}) into a named constant near the top of the module so it’s easier to reuse, audit, and extend in one place. - The
_safe_eval_typemethod is now complex enough to triggerC901; if possible, factor the AST validation (including theast.Callchecks) into a dedicated helper/visitor class or function to keep_safe_eval_typefocused on orchestration.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Consider extracting the hard-coded callable whitelist (`{"Depends", "depends", "Field", "PrivateAttr", "Tag"}`) into a named constant near the top of the module so it’s easier to reuse, audit, and extend in one place.
- The `_safe_eval_type` method is now complex enough to trigger `C901`; if possible, factor the AST validation (including the `ast.Call` checks) into a dedicated helper/visitor class or function to keep `_safe_eval_type` focused on orchestration.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 hardens the DI container’s string-based type evaluation to mitigate an Arbitrary Code Execution (ACE) vector introduced by permitting arbitrary ast.Call nodes to reach eval().
Changes:
- Adds an
ast.Callwhitelist inContainer._safe_eval_type()to restrict which callables may be invoked when evaluating type strings. - Documents the vulnerability, root cause, and prevention strategy in the Sentinel security log.
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 callable execution during safe type-string evaluation by validating ast.Call nodes against an allowlist. |
.jules/sentinel.md |
Records the ACE finding and the mitigation approach in the security log. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if isinstance(node, ast.Call): | ||
| if isinstance(node.func, ast.Name): | ||
| func_name = node.func.id | ||
| elif isinstance(node.func, ast.Attribute): | ||
| func_name = node.func.attr | ||
| else: | ||
| raise TypeError("Forbidden call representation in type string") | ||
|
|
||
| if func_name not in {"Depends", "depends", "Field", "PrivateAttr", "Tag"}: | ||
| raise TypeError(f"Forbidden callable in type string: {func_name}") |
| # Restrict ast.Call to a strict whitelist to prevent Arbitrary Code Execution (ACE). | ||
| # Allowing generic ast.Call permits execution of any callable in the module's | ||
| # global namespace during eval(), introducing a critical ACE vulnerability. | ||
| if isinstance(node, ast.Call): | ||
| if isinstance(node.func, ast.Name): |
🚨 Severity: CRITICAL
💡 Vulnerability: Arbitrary Code Execution (ACE) vulnerability found in
src/codeweaver/core/di/container.pywithin the_safe_eval_typefunction. The function allowed genericast.Callnodes inside type strings, which, when passed toeval(), permitted execution of any callable available in the module's global namespace.🎯 Impact: An attacker or malicious configuration string could inject arbitrary code via unvalidated or manipulated string type annotations that get evaluated by the container.
🔧 Fix: Restrict
ast.Callexecution by verifying the function name (vianode.func.idornode.func.attr) against a strict whitelist containing explicitly allowed callables ({"Depends", "depends", "Field", "PrivateAttr", "Tag"}). Added a comment explaining the fix.✅ Verification: Ran
mise //:checkfor linting and formatting. Executed test suite targeting the modified file (tests/unit/core/di/test_container.pyandtests/unit/core/di/test_container_phase1.py) and verified no regressions. Created a manual proof of concept script that confirmed the vulnerability and successfully verified the fix blocked execution.PR created automatically by Jules for task 16264884343887620784 started by @bashandbone
Summary by Sourcery
Harden safe type evaluation in the DI container to eliminate an arbitrary code execution vector and document the security learning in Sentinel notes.
Bug Fixes:
_safe_eval_typeby restrictingast.Callnodes to a strict whitelist of allowed callables in type strings.Documentation:
_safe_eval_type, the root cause, and the prevention strategy.