Skip to content

fix(tools): pin FileWriterTool writes to the workspace directory#6201

Open
Jiangrong-W wants to merge 1 commit into
crewAIInc:mainfrom
Jiangrong-W:harness-fix/crewai-h-filewriter-directory-policy-bypass
Open

fix(tools): pin FileWriterTool writes to the workspace directory#6201
Jiangrong-W wants to merge 1 commit into
crewAIInc:mainfrom
Jiangrong-W:harness-fix/crewai-h-filewriter-directory-policy-bypass

Conversation

@Jiangrong-W

@Jiangrong-W Jiangrong-W commented Jun 17, 2026

Copy link
Copy Markdown

FileWriterTool already rejected filename escapes (../, absolute filename, symlink) by checking that the resolved path is relative to the target directory. However, that directory is itself a fully model-controlled argument with no workspace anchoring, so an absolute root such as /etc/cron.d or ~/.ssh passed as directory resolved the final path "inside" an attacker-chosen root and the containment check passed — yielding an out-of-workspace write (and os.makedirs of the chosen root) with no non-default flag.

Anchor the resolved write target to the current working directory using validate_file_path() from crewai_tools.security.safe_path — the same cwd-pinned validator FileReadTool already uses. The existing is_relative_to() filename-escape guard is kept as defense in depth.

The documented CREWAI_TOOLS_ALLOW_UNSAFE_PATHS escape hatch continues to let callers opt in to writes outside the workspace, so explicit/trusted usage stays backward compatible. The public _run() signature is unchanged.

Existing tests that wrote to absolute temp dirs are updated to run inside an isolated workspace (the established FileReadTool test idiom). New regression tests cover the directory-as-root vector and the opt-in escape hatch.

Summary by CodeRabbit

  • Tests
    • Enhanced security test coverage for FileWriterTool to validate path confinement behavior and prevent unauthorized writes outside the workspace directory.
    • Added tests confirming the tool rejects writes to absolute paths outside the workspace and supports optional unsafe path handling via environment variable.

FileWriterTool already rejected filename escapes (../, absolute
filename, symlink) by checking that the resolved path is relative to
the target directory. However, that directory is itself a fully
model-controlled argument with no workspace anchoring, so an absolute
root such as /etc/cron.d or ~/.ssh passed as `directory` resolved the
final path "inside" an attacker-chosen root and the containment check
passed — yielding an out-of-workspace write (and os.makedirs of the
chosen root) with no non-default flag.

Anchor the resolved write target to the current working directory using
validate_file_path() from crewai_tools.security.safe_path — the same
cwd-pinned validator FileReadTool already uses. The existing
is_relative_to() filename-escape guard is kept as defense in depth.

The documented CREWAI_TOOLS_ALLOW_UNSAFE_PATHS escape hatch continues to
let callers opt in to writes outside the workspace, so explicit/trusted
usage stays backward compatible. The public _run() signature is
unchanged.

Existing tests that wrote to absolute temp dirs are updated to run inside
an isolated workspace (the established FileReadTool test idiom). New
regression tests cover the directory-as-root vector and the opt-in
escape hatch.

Signed-off-by: christop <825583681@qq.com>
@Jiangrong-W Jiangrong-W changed the title Pin FileWriterTool writes to the workspace directory fix(tools): pin FileWriterTool writes to the workspace directory Jun 17, 2026
@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 77199395-5cdb-43ee-96e7-e90a5124c7b5

📥 Commits

Reviewing files that changed from the base of the PR and between 7bb9bc7 and 4901713.

📒 Files selected for processing (2)
  • lib/crewai-tools/src/crewai_tools/tools/file_writer_tool/file_writer_tool.py
  • lib/crewai-tools/tests/tools/test_file_writer_tool.py

📝 Walkthrough

Walkthrough

The temp_env pytest fixture is updated to use tmp_path and monkeypatch.chdir for workspace isolation. Three new tests are added to verify FileWriterTool rejects absolute out-of-workspace directory paths, creates no filesystem state outside the workspace, omits path details from error messages, and permits writes when CREWAI_TOOLS_ALLOW_UNSAFE_PATHS is set.

Changes

FileWriterTool path confinement test coverage

Layer / File(s) Summary
temp_env fixture isolation update
lib/crewai-tools/tests/tools/test_file_writer_tool.py
temp_env fixture is rewritten to create a workspace subdirectory under pytest's tmp_path and change the working directory into it via monkeypatch.chdir, replacing the prior tempfile.mkdtemp() approach.
Out-of-workspace write rejection and escape hatch tests
lib/crewai-tools/tests/tools/test_file_writer_tool.py
Adds test_blocks_absolute_directory_outside_workspace, test_does_not_create_directory_outside_workspace, and test_escape_hatch_allows_outside_workspace_write to assert that FileWriterTool rejects out-of-workspace absolute paths, produces no filesystem side effects, does not leak path prefixes in the error message, and allows writes when CREWAI_TOOLS_ALLOW_UNSAFE_PATHS is explicitly set.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly describes the main security fix: pinning FileWriterTool writes to the workspace directory, which directly addresses the vulnerability detailed in the objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant