crewAIInc / crewAIInc/crewAI

[BUG] Two path-containment security tests fail on Windows without symlink privilege

Open Beginner friendly
#7,431 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

Description

Two tests in lib/crewai-tools create symlinks in setup with no guard, so they fail on Windows for any user who is not elevated and does not have Developer Mode enabled:

OSError: [WinError 1314] A required privilege is not held by the client
tests/utilities/test_safe_path.py:53 — test_rejects_symlink_escape
os.symlink("/etc/passwd", str(link))
tests/tools/test_file_writer_tool.py:216 — test_blocks_symlink_escape
os.symlink(outside_dir, link)
Both are security regression tests — they assert that a symlink cannot be used to escape the allowed directory. So the practical effect is that the two tests guarding crewAI's path-containment (the same behaviour hardened in #6248 and #6249) are exactly the ones an ordinary Windows contributor cannot run; their suite comes back red in setup.

Steps to Reproduce

Why CI doesn't catch it

The workflow matrix runs ubuntu-latest and macos-*; no job runs the suite on Windows. GitHub's runners can create symlinks anyway, so even a Windows job would pass — the gap is a privilege one, not just a platform one.

Expected behavior

The product code is fine

Worth stating so this isn't mistaken for a security report: validate_file_path in lib/crewai-tools/src/crewai_tools/security/safe_path.py uses os.path.realpath() then a prefix containment check. realpath() resolves junctions as well as symlinks on Windows, so the containment itself holds. This is only about the tests being unable to run.

Screenshots/Code snippets
Operating System

Ubuntu 20.04

Python Version

3.10

crewAI Version
crewAI Tools Version
Virtual Environment

Venv

Evidence

..

Possible Solution

Suggested fix (happy to PR once this is triaged)
A small helper that skips only the privilege case and re-raises every other OSError, so a genuine setup failure never turns into a passing skip:

def _symlink_or_skip(src, dst):
try:
os.symlink(src, dst)
except OSError as e:
if os.name == "nt" and getattr(e, "winerror", None) == 1314:
pytest.skip("symlink creation requires elevated privileges on Windows")
raise
Used at the two call sites. Where symlinks work — every current CI job, and any elevated or Developer Mode machine — behaviour is unchanged, and the escape assertions still run.

Additional context

Environment
Windows 11 (10.0.26200), Python 3.13, non-elevated, Developer Mode off
crewAI at HEAD (lib/crewai-tools)

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 tests/utilities/test_safe_path.py at test_rejects_symlink_escape and tests/tools/test_file_writer_tool.py at test_blocks_symlink_escape. Add or use a shared helper that skips only Windows WinError 1314 during symlink setup and re-raises other OSError values. Run both tests on Windows and a platform where symlinks work; done means the security assertions still run when possible and unprivileged Windows setup skips cleanly.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
security, testing-qa
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
86/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.