crewai - ✅(Solved) Fix [Security] Command Injection and Sandbox Escape in CodeInterpreterTool [2 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
crewAIInc/crewAI#4516Fetched 2026-04-08 00:41:37
View on GitHub
Comments
1
Participants
2
Timeline
9
Reactions
0
Timeline (top)
cross-referenced ×5referenced ×2closed ×1commented ×1

I've identified two security vulnerabilities in the CodeInterpreterTool component:

  1. Command Injection (CWE-78) in run_code_unsafe()
  2. Sandbox Escape (CWE-94) in run_code_in_restricted_sandbox()

Root Cause

I've identified two security vulnerabilities in the CodeInterpreterTool component:

  1. Command Injection (CWE-78) in run_code_unsafe()
  2. Sandbox Escape (CWE-94) in run_code_in_restricted_sandbox()

Fix Action

Fixed

PR fix notes

PR #4517: Fix: Command Injection and Sandbox Escape in CodeInterpreterTool (#4516)

Description (problem / solution / changelog)

Fix: Command Injection and Sandbox Escape in CodeInterpreterTool (#4516)

Summary

Addresses two security vulnerabilities reported in #4516:

  1. Command Injection (CWE-78): run_code_unsafe() passed user-provided library names directly to os.system(), enabling shell command injection. Fixed by replacing with subprocess.run() using list arguments, which avoids shell interpretation.

  2. Sandbox Escape (CWE-94): SandboxPython failed to block Python object introspection methods (__class__, __bases__, __subclasses__, etc.) that allow traversing the object hierarchy to access blocked modules. Fixed by:

    • Adding a BLOCKED_ATTRS set of dangerous dunder attributes
    • Adding a regex-based pre-execution scan (_check_for_blocked_attrs) that rejects code containing these patterns
    • Adding getattr, setattr, delattr, type, breakpoint to UNSAFE_BUILTINS

17 new tests added covering both vulnerability classes.

Updates since last revision

  • Fixed noqa comment placement: S603 suppression moved to the subprocess.run( line (where ruff expects it), S607 remains on the args line.
  • Unrelated change in tool.specs.json came in via merge with main (removes AvailableModel enum and model_name from Web Automation Tool specs) — not part of this fix.

Review & Testing Checklist for Human

  • Blocking type as a builtin is aggressivetype(x) is extremely common in normal Python for type-checking. This will break legitimate sandbox code that uses type(). Decide whether to keep it blocked, allowlist single-arg type(), or remove it from UNSAFE_BUILTINS.
  • Regex static analysis produces false positives on string literals_check_for_blocked_attrs matches at the string level, so code like x = "__class__" or # comment mentioning __bases__ will be rejected even though it's harmless. Evaluate if this trade-off is acceptable.
  • Regex static analysis can be bypassed by determined attackers — Dynamic attribute construction (e.g., chr(95)+chr(95)+...) or indirect access patterns could evade string-level detection. getattr/setattr are also blocked (reducing attack surface), but this is defense-in-depth, not a complete solution. Consider whether mandatory Docker or RestrictedPython is warranted for stronger guarantees.
  • Unused MagicMock import in test file — minor, was added but never used.

Suggested test plan: Run the full code interpreter test suite, then manually try common sandbox patterns — especially type(x), string literals containing dunder names, and basic arithmetic/list operations — to verify no regressions in legitimate use cases.

Notes

Requested by: João Link to Devin run

Changed files

  • lib/crewai-tools/src/crewai_tools/tools/code_interpreter_tool/code_interpreter_tool.py (modified, +40/-1)
  • lib/crewai-tools/tests/tools/test_code_interpreter_tool.py (modified, +226/-1)
  • lib/crewai-tools/tool.specs.json (modified, +0/-23)

PR #4643: Fix command injection and sandbox escape in CodeInterpreterTool

Description (problem / solution / changelog)

Fixes the two security issues reported in #4516.

The first issue is command injection in pip install. The library name was interpolated into an os.system() call, so a crafted library name like "numpy; rm -rf /" could execute arbitrary commands. Fixed by switching to subprocess.run() with the arguments as a list, which prevents shell interpretation of special characters.

The second issue is sandbox escape via subclasses() introspection. Python's object model lets you walk up from any object to builtins through ().class.bases[0].subclasses(), which gives access to every loaded class including importers that can load blocked modules like os. Fixed by checking submitted code for class, bases, subclasses, mro, and qualname before execution, and also blocking getattr, setattr, delattr, and breakpoint from the sandbox builtins to close related bypass paths.

Both fixes include new tests. All 20 tests in the code interpreter test file pass, including the 9 pre-existing ones.

<!-- CURSOR_SUMMARY -->

[!NOTE] Medium Risk Touches security-sensitive code execution paths and may block previously-working sandbox code that used introspection or dynamic attribute access. Changes are localized and covered by new regression tests.

Overview Security hardening for CodeInterpreterTool. Unsafe-mode dependency installs now use subprocess.run(["pip","install",...], check=True) instead of os.system, returning a clear error on install failure and preventing library-name command injection.

The restricted sandbox now blocks additional dangerous builtins (e.g., getattr/setattr) and rejects code containing restricted dunder attribute names (e.g., __class__, __subclasses__) before execution to mitigate introspection-based escapes. New tests assert both fixes and confirm normal sandbox code still runs.

<sup>Written by Cursor Bugbot for commit 394c8396e8aea15d4b1e9070aab38f13e4b13632. This will update automatically on new commits. Configure here.</sup>

<!-- /CURSOR_SUMMARY -->

Changed files

  • lib/crewai-tools/src/crewai_tools/tools/code_interpreter_tool/code_interpreter_tool.py (modified, +38/-1)
  • lib/crewai-tools/tests/tools/test_code_interpreter_tool.py (modified, +132/-0)
RAW_BUFFERClick to expand / collapse

Summary

I've identified two security vulnerabilities in the CodeInterpreterTool component:

  1. Command Injection (CWE-78) in run_code_unsafe()
  2. Sandbox Escape (CWE-94) in run_code_in_restricted_sandbox()

Vulnerability 1: Command Injection via Library Names

Location: lib/crewai-tools/src/crewai_tools/tools/code_interpreter_tool/code_interpreter_tool.py lines 378-379

Code: ```python for library in libraries_used: os.system(f"pip install {library}") # noqa: S605 ```

Description: User-provided library names from `CodeInterpreterSchema.libraries_used` are passed directly to `os.system()` without sanitization.

PoC: ```python from crewai_tools import CodeInterpreterTool

tool = CodeInterpreterTool(unsafe_mode=True) result = tool._run( code="result = 'test'", libraries_used=["numpy; id #"] # Executes arbitrary command ) ```

Impact: Remote code execution when `unsafe_mode=True`

Fix: Use `subprocess.run(["pip", "install", library])` with list arguments.

Vulnerability 2: Restricted Sandbox Escape

Location: `SandboxPython` class (lines 67-130)

Description: The sandbox blocks certain modules/builtins but fails to block Python object introspection methods that allow bypassing the restrictions.

NOT blocked: `type`, `getattr`, `setattr`, `object`, `breakpoint`, `class`, `bases`, `subclasses`

PoC: ```python

Access blocked 'os' module via object introspection

code = """ for c in ().class.bases[0].subclasses(): if c.name == 'BuiltinImporter': result = c.load_module('os').system('id') break """ ```

Impact: Complete sandbox bypass when Docker is unavailable and code runs in "safe" mode

Fix:

  • Block `class`, `bases`, `subclasses`, `mro`
  • Consider using RestrictedPython or requiring Docker for all code execution

Severity

  • Command Injection: CVSS 7.5-8.0 (High) - requires unsafe_mode
  • Sandbox Escape: CVSS 8.5-9.0 (Critical) - affects default safe mode

Disclosure

I'm submitting this as a GitHub issue for responsible disclosure. Happy to provide additional details or assist with remediation.


Reported by: optimus-fulcria (AI Security Researcher)

extent analysis

Fix Plan

To address the security vulnerabilities, follow these steps:

Command Injection Fix

  1. Replace os.system with subprocess.run: Use the subprocess module to execute the pip install command with a list of arguments.
  2. Sanitize library names: Validate and sanitize user-provided library names to prevent command injection.

Example code:

import subprocess

for library in libraries_used:
    subprocess.run(["pip", "install", library])

Sandbox Escape Fix

  1. Block object introspection methods: Restrict access to __class__, __bases__, __subclasses__, and __mro__ attributes.
  2. Consider using RestrictedPython: Evaluate the use of RestrictedPython to provide a more secure execution environment.
  3. Require Docker for code execution: Enforce the use of Docker for all code execution to prevent sandbox bypass.

Example code (blocking object introspection methods):

class SandboxPython:
    # ...

    def __getattribute__(self, name):
        if name in ["__class__", "__bases__", "__subclasses__", "__mro__"]:
            raise AttributeError(f"Access to '{name}' is restricted")
        return super().__getattribute__(name)

Verification

To verify the fixes, test the following scenarios:

  • Command injection: Attempt to inject malicious commands using the libraries_used parameter.
  • Sandbox escape: Try to access blocked modules or execute arbitrary code using object introspection methods.

Extra Tips

  • Regularly review and update the SandboxPython class to ensure it remains secure.
  • Consider implementing additional security measures, such as input validation and error handling.
  • Keep the subprocess module up to date to prevent potential vulnerabilities.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING