crewAIInc / crewAIInc/crewAI

training data pickle.load (no integrity check) + Agent Repository importlib.import_module on remote JSON (no allowlist)

Open
#6,798 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

no-issue-activity
Dominant language
Python
Stars
58.8k
Forks
8.5k
Avg merge
1d 15h
Merged PRs (30d)
109

Description

What

Two unsafe primitives in crewAI's training and agent-repository paths:

  1. Unsafe deserialization on training dataPickleHandler.load (lib/crewai/src/crewai/utilities/file_handler.py:166) does return pickle.load(file) # noqa: S301 with no integrity check. The training_data.pkl / trained-agents pkl file lives in the working directory and is loaded on every task execution of a training-enabled crew (agent/core.py:1282 _training_handler:1309 _use_trained_data). Any actor that can write the cwd (shared CI, multi-user host, co-tenant process) plants a malicious pickle → arbitrary code execution on the next trained crew kickoff. The loaded values are also injected verbatim into agent prompts as instructions (core.py:1289-1292).

  2. Unsandboxed module import from remote Agent Repositoryload_agent_from_repository (lib/crewai/src/crewai/utilities/agent_utils.py:1240-1243) takes tool definitions from the AMP get_agent() response and does importlib.import_module(tool["module"]) + tool_class(**tool["init_params"]) with no module allowlist. A compromised AMP endpoint, MITM, or a malicious agent published to the org yields import of any importable module plus constructor execution with attacker-controlled arguments — RCE without any local file write.

Checked at b10c4ff (HEAD main).

How to reproduce

# 1. pickle.load runs arbitrary code (the pattern PickleHandler.load uses)
import pickle
class P:
    def __reduce__(self):
        return (print, ("RCE via training_data.pkl",))
# write pickle.dumps(P()) to training_data.pkl in the crew's cwd → loads on next trained task

# 2. remote import — any module named in the AMP get_agent() response is imported
# agent_utils.py:1240: module = importlib.import_module(tool["module"])  # no allowlist
# agent_utils.py:1243: tool_class(**tool["init_params"])  # attacker-controlled args

Impact

  • Training pickle: RCE as the crew process. Requires write access to the cwd (training is opt-in via crew.train(), but once training_data.pkl exists the load is automatic on every task).
  • Remote import: RCE via compromised/MIITM AMP endpoint or malicious org-published agent. Requires Agent(from_repository=...) usage.

Suggested change

  • Replace pickle.load on training data with a safe format (JSON) or add an integrity check (HMAC/signature over the pkl file). The # noqa: S301 suppression acknowledges the risk but doesn't mitigate it.
  • Validate tool["module"] against an allowlist before importlib.import_module; reject unknown modules or require explicit operator approval for each import.

Happy to open a PR for either.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with PickleHandler.load in lib/crewai/src/crewai/utilities/file_handler.py and the _training_handler/_use_trained_data paths in agent/core.py, then inspect load_agent_from_repository in utilities/agent_utils.py. Trace how training files and AMP tool definitions reach these entry points, and review existing security tests if present. Done means both paths reject untrusted execution while preserving supported training and repository behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend-api-design, security
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.