.Net: Harden file path validation in Core, Document, and Web plugins#14118
Merged
SergeyMenshykh merged 4 commits intoJun 25, 2026
Conversation
Introduce a shared PathUtilities.GetSafeFullPath helper that canonicalizes file system paths and use it across the file-based plugins so that path allowlist checks and the subsequent file I/O operate on the same canonical path. Adds regression tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR hardens filesystem path handling across several .NET file-based plugins by introducing a shared canonicalization helper (PathUtilities.GetSafeFullPath) that resolves paths consistently (including symlink-aware resolution on .NET 6+) so that allowlist validation and subsequent file I/O operate on the same resolved location.
Changes:
- Added
PathUtilities.GetSafeFullPathand updated plugins to use it for canonicalization and OS-appropriate path comparisons. - Hardened allowlist validation logic to reduce validate/use mismatches (including symlink bypass scenarios).
- Added regression tests covering symlink bypass and Linux case-sensitive allowlist behavior; linked
PathUtilities.csinto the unit test project.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| dotnet/src/InternalUtilities/src/System/PathUtilities.cs | Introduces shared safe full-path canonicalization with symlink-aware resolution. |
| dotnet/src/Plugins/Plugins.Core/FileIOPlugin.cs | Uses canonical path for both allowlist checks and I/O; switches to OS-appropriate comparison. |
| dotnet/src/Plugins/Plugins.Core/CodeInterpreter/SessionsPythonPlugin.cs | Uses safe canonicalization for upload/download validation and directory comparisons. |
| dotnet/src/Plugins/Plugins.Document/DocumentPlugin.cs | Switches canonicalization and comparisons to PathUtilities to avoid validate/use mismatches. |
| dotnet/src/Plugins/Plugins.Web/WebFileDownloadPlugin.cs | Canonicalizes download paths via helper and compares paths using PathUtilities.PathComparison. |
| dotnet/src/Plugins/Plugins.UnitTests/Plugins.UnitTests.csproj | Links PathUtilities.cs into unit tests to validate behavior directly. |
| dotnet/src/Plugins/Plugins.UnitTests/Core/PathUtilitiesTests.cs | Adds direct tests for canonicalization and symlink handling behaviors. |
| dotnet/src/Plugins/Plugins.UnitTests/Core/FileIOPluginTests.cs | Adds tests for symlink-bypass denial and Linux case-sensitive allowlist behavior. |
| dotnet/src/Plugins/Plugins.UnitTests/Core/SessionsPythonPluginTests.cs | Adds tests for symlink-bypass denial and Linux casing behavior in upload/download validation. |
| dotnet/src/Plugins/Plugins.UnitTests/Web/WebFileDownloadPluginTests.cs | Adds tests for UNC/extended path rejection and Linux case-sensitive allowlist behavior. |
Comments suppressed due to low confidence (1)
dotnet/src/Plugins/Plugins.Core/FileIOPlugin.cs:119
- UNC paths can be specified with forward slashes (e.g., "//server/share/file") on Windows. Currently only "\\" is rejected, so "//" can slip through to PathUtilities.GetSafeFullPath / File.Exists before being denied, potentially causing unintended network access or hangs. Reject "//" here as well, consistent with other plugins’ UNC checks.
if (path.StartsWith("\\\\", StringComparison.OrdinalIgnoreCase))
{
throw new ArgumentException("Invalid file path, UNC paths are not supported.", nameof(path));
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Add missing System.Runtime.InteropServices using to PathUtilities so it compiles where implicit usings are disabled. - Reject forward-slash UNC paths in DocumentPlugin, consistent with the Web plugin, and add a regression test. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
rogerbarreto
approved these changes
Jun 24, 2026
Catch only the privilege exceptions (IOException/UnauthorizedAccessException) when creating symbolic links and remove the File.Exists/Directory.Exists guards, so genuine test-setup failures surface instead of being masked. The early return is retained only for environments (e.g. Windows build agents) that don't permit symbolic link creation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
westey-m
approved these changes
Jun 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation and Context
This change hardens file system path handling in the file-based plugins. Previously, the path used for allowlist validation could differ from the path ultimately used for file I/O, so the two operations were not guaranteed to refer to the same file system location.
Description
PathUtilities.GetSafeFullPathhelper that produces a canonical full path for a given input.FileIOPlugin,SessionsPythonPlugin,DocumentPluginandWebFileDownloadPluginto validate and perform I/O against the same canonical path, and to compare paths using OS-appropriate string comparison.Contribution Checklist