Skip to content

.Net: Add deny-by-default AllowedUploadDirectories to CloudDrivePlugin#13953

Open
SergeyMenshykh wants to merge 7 commits intomicrosoft:mainfrom
SergeyMenshykh:msgraph-allow-upload-directories
Open

.Net: Add deny-by-default AllowedUploadDirectories to CloudDrivePlugin#13953
SergeyMenshykh wants to merge 7 commits intomicrosoft:mainfrom
SergeyMenshykh:msgraph-allow-upload-directories

Conversation

@SergeyMenshykh
Copy link
Copy Markdown
Member

Description

Add deny-by-default AllowedUploadDirectories to CloudDrivePlugin.

  • Added AllowedUploadDirectories property (defaults to empty = deny-all)
  • UploadFileAsync now validates the local file path against the allowlist before uploading
  • Paths are canonicalized with environment variable expansion, UNC rejection, and directory traversal protection
  • Added unit tests for the new behavior

- Add AllowedUploadDirectories property (defaults to empty = deny-all)
- Validate local file path against allowlist before uploading
- Canonicalize paths with env var expansion, UNC rejection, and traversal protection
- Add unit tests for security behavior

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 5, 2026 09:35
@SergeyMenshykh SergeyMenshykh requested a review from a team as a code owner May 5, 2026 09:35
@moonbox3 moonbox3 added the .NET Issue or Pull requests regarding .NET code label May 5, 2026
@github-actions github-actions Bot changed the title Add deny-by-default AllowedUploadDirectories to CloudDrivePlugin .Net: Add deny-by-default AllowedUploadDirectories to CloudDrivePlugin May 5, 2026
@SergeyMenshykh SergeyMenshykh self-assigned this May 5, 2026
@SergeyMenshykh SergeyMenshykh moved this to In Review in Agent Framework May 5, 2026
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Automated Code Review

Reviewers: 4 | Confidence: 89%

✓ Correctness

This PR adds path-allowlisting security to CloudDrivePlugin's upload functionality. The implementation correctly canonicalizes paths (expanding environment variables and resolving traversal), validates against an explicit allowlist, blocks UNC paths, and permits subdirectories of allowed directories. The logic in IsUploadPathAllowed is sound — it properly handles trailing separators to prevent prefix attacks (e.g., /tmp/allowed vs /tmp/allowed-evil). Tests cover the key scenarios including default-deny, traversal, UNC, subdirectories, and environment variable expansion. No blocking correctness issues found.

✓ Security Reliability

This PR adds a security allowlist for upload directories in CloudDrivePlugin, implementing a deny-by-default pattern. The implementation correctly canonicalizes paths before validation (preventing traversal), expands environment variables before checking the allowlist, blocks UNC paths, and handles subdirectory matching with proper trailing-separator logic. The design is sound and well-tested. No blocking security or reliability issues identified.

✓ Test Coverage

The PR adds good security guardrails to CloudDrivePlugin with an AllowedUploadDirectories allowlist, and includes solid test coverage for the core security scenarios (default deny, path traversal, UNC paths, subdirectory access). However, there is a cross-platform fragility concern in the environment variable expansion test that relies on %TEMP% being set (Windows-only convention), and the existing success test mises an opportunity to verify that the canonicalized path (not the raw input) is forwarded to the connector.

✗ Design Approach

The new upload allowlist closes a real security gap, but the way it is introduced creates two design problems: it is a silent runtime-breaking change for existing CloudDrivePlugin consumers because the new policy is only configurable through an optional mutable property, and the path-matching logic hard-codes case-insensitive Windows semantics into a plugin that is exercised on Linux as well. Both issues point to the same root problem: the security policy needs to be modeled as an explicit, cross-platform contract rather than bolted onto UploadFileAsync as ad-hoc string checks.

Flagged Issues

  • The allowlist uses OrdinalIgnoreCase path matching even though the repo runs .NET on Ubuntu (.github/workflows/dotnet-build-and-test.yml:59-67, .github/workflows/dotnet-ci.yml:22-25), so on Linux it can treat distinct directories (e.g., /tmp/Allowed vs /tmp/allowed) as equivalent, admitting files outside the intended allowlist.

Automated review by SergeyMenshykh's agents

Comment thread dotnet/src/Plugins/Plugins.MsGraph/CloudDrivePlugin.cs Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 adds a deny-by-default local path allowlist (AllowedUploadDirectories) to CloudDrivePlugin so uploads are blocked unless explicitly configured, aiming to reduce the risk of unintended local file exfiltration when the plugin is exposed via auto function calling.

Changes:

  • Introduces AllowedUploadDirectories (default deny-all) and validates upload filePath against it after canonicalization.
  • Adds path canonicalization logic (env var expansion + GetFullPath) and explicit UNC rejection.
  • Updates/extends unit tests to cover the new allowlist behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.

File Description
dotnet/src/Plugins/Plugins.MsGraph/CloudDrivePlugin.cs Adds allowlist property and enforces deny-by-default upload path validation.
dotnet/src/Plugins/Plugins.UnitTests/MsGraph/CloudDrivePluginTests.cs Updates the existing upload test and adds new tests for deny/allow scenarios.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread dotnet/src/Plugins/Plugins.MsGraph/CloudDrivePlugin.cs
Comment thread dotnet/src/Plugins/Plugins.MsGraph/CloudDrivePlugin.cs Outdated
Comment thread dotnet/src/Plugins/Plugins.MsGraph/CloudDrivePlugin.cs Outdated
Comment thread dotnet/src/Plugins/Plugins.MsGraph/CloudDrivePlugin.cs Outdated
Comment thread dotnet/src/Plugins/Plugins.UnitTests/MsGraph/CloudDrivePluginTests.cs Outdated
SergeyMenshykh and others added 2 commits May 5, 2026 10:47
Use OrdinalIgnoreCase on Windows and Ordinal on Linux/macOS to
respect case-sensitive file systems. Add test for platform-aware
case sensitivity behavior.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Validate filePath before canonicalization to provide a clear error.
Include AllowedUploadDirectories remediation hint in deny message.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
SergeyMenshykh and others added 2 commits May 5, 2026 12:00
…d filePath guard

- Make AllowedUploadDirectories non-nullable; null assignments treated as empty (deny-all)
- Add filePath null/whitespace guard before canonicalization
- Include AllowedUploadDirectories hint in deny error message

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Use specific ArgumentException assertion for UNC path test
- Use dedicated test env var instead of platform-specific TEMP
- Restore env var in finally blocks for test isolation

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
On Linux, UNC paths are canonicalized differently and hit the
allowlist denial (InvalidOperationException) instead of the UNC
check (ArgumentException). Both correctly deny the upload.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@SergeyMenshykh SergeyMenshykh deployed to integration May 5, 2026 13:11 — with GitHub Actions Active
@SergeyMenshykh SergeyMenshykh enabled auto-merge May 5, 2026 13:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

.NET Issue or Pull requests regarding .NET code

Projects

Status: In Review

Development

Successfully merging this pull request may close these issues.

3 participants