Skip to content

Python: Reject Windows junctions in FileSystemAgentFileStore - #7291

Merged
eavanvalkenburg merged 3 commits into
microsoft:mainfrom
sricursion:codex/fix-python-file-store-junctions
Jul 27, 2026
Merged

Python: Reject Windows junctions in FileSystemAgentFileStore#7291
eavanvalkenburg merged 3 commits into
microsoft:mainfrom
sricursion:codex/fix-python-file-store-junctions

Conversation

@sricursion

@sricursion sricursion commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Motivation & Context

FileSystemAgentFileStore promises root-scoped access and rejects linked or reparse paths during direct operations, but its directory listing and recursive search paths only checked Path.is_symlink(). On Windows, directory junctions are reparse points that do not report as symlinks, so file_access_grep could descend outside the configured root.

Description & Review Guide

  • What are the major changes? Add a shared link and reparse-point predicate using lstat(), POSIX link mode, Path.is_junction() when available, and the Windows reparse attribute fallback. Apply it to direct path validation, directory listing, and recursive search, and add a Windows regression test with a real directory junction.
  • What is the impact of these changes? FileSystemAgentFileStore now consistently omits symlinks, junctions, and other reparse points from listing and search, preventing recursive file access from crossing the configured root. Existing regular-file behavior and public APIs are unchanged.
  • What do you want reviewers to focus on? The cross-version Windows reparse detection and fail-closed behavior when an entry cannot be inspected.

Related Issue

Fixes #7290

Contribution Checklist

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This PR is linked to an issue and there is no other open PR for this issue (see Related Issue above).
  • This is not a breaking change. If it is a breaking change, add the breaking change label (or add [BREAKING] to the title prefix, before or after any language prefix) - a workflow keeps the label and title prefix in sync automatically.

Copilot AI review requested due to automatic review settings July 23, 2026 13:02
@sricursion
sricursion temporarily deployed to github-app-auth July 23, 2026 13:02 — with GitHub Actions Inactive
@sricursion
sricursion temporarily deployed to github-app-auth July 23, 2026 13:02 — with GitHub Actions Inactive
@sricursion
sricursion temporarily deployed to github-app-auth July 23, 2026 13:02 — with GitHub Actions Inactive
@sricursion
sricursion temporarily deployed to github-app-auth July 23, 2026 13:03 — with GitHub Actions Inactive
@agent-framework-automation agent-framework-automation Bot added the python Usage: [Issues, PRs], Target: Python label Jul 23, 2026
@sricursion
sricursion temporarily deployed to github-app-auth July 23, 2026 13:05 — with GitHub Actions Inactive
@sricursion
sricursion temporarily deployed to github-app-auth July 23, 2026 13:05 — with GitHub Actions Inactive

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens the Python FileSystemAgentFileStore containment boundary on Windows by treating NTFS directory junctions (and other reparse points) as link-like entries during listing and recursive search, preventing enumeration from escaping the configured root.

Changes:

  • Introduces a shared _is_link_or_reparse_point() predicate (symlink + junction + Windows reparse attribute) and uses it across direct path validation, directory listing, and recursive search enumeration.
  • Updates link/reparse probing to be lstat()-based and fail-closed when link/reparse status cannot be determined.
  • Adds a Windows regression test that creates a real directory junction and asserts that read/list/search do not traverse it.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
python/packages/core/agent_framework/_harness/_file_access.py Adds unified link/reparse detection and applies it consistently to validation, listing, and recursive search enumeration.
python/packages/core/tests/core/test_harness_file_access.py Adds a Windows junction regression test and updates the fail-closed probe test to patch Path.lstat.

Comment thread python/packages/core/agent_framework/_harness/_file_access.py
@sricursion

Copy link
Copy Markdown
Contributor Author

@microsoft-github-policy-service agree

@sricursion
sricursion marked this pull request as ready for review July 23, 2026 13:38
@sricursion
sricursion temporarily deployed to github-app-auth July 23, 2026 13:38 — with GitHub Actions Inactive
@sricursion
sricursion temporarily deployed to github-app-auth July 23, 2026 15:55 — with GitHub Actions Inactive
@sricursion
sricursion temporarily deployed to github-app-auth July 23, 2026 15:59 — with GitHub Actions Inactive
@github-actions

Copy link
Copy Markdown
Contributor

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/core/agent_framework/_harness
   _file_access.py6345092%93, 203, 234, 297, 407, 409, 421, 425, 453, 466–467, 474–481, 485, 489, 855–856, 881, 885, 940–942, 964–967, 1006, 1008, 1065, 1067, 1471–1472, 1483–1484, 1496–1497, 1511–1512, 1535–1536, 1551, 1556–1557, 1586
TOTAL45539447390% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
9386 34 💤 0 ❌ 0 🔥 2m 30s ⏱️

@eavanvalkenburg
eavanvalkenburg added this pull request to the merge queue Jul 27, 2026
Merged via the queue into microsoft:main with commit 5ccd778 Jul 27, 2026
46 of 48 checks passed
@sricursion

Copy link
Copy Markdown
Contributor Author

Thanks Eduard and Westey.

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

Labels

python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python: [Bug]: FileSystemAgentFileStore recursive search follows Windows junctions outside its configured root

4 participants