<!-- Anything that looks like this is a comment and can't be seen after the Pull Request is created. --> ### PR Summary Fix: [[MSRC 118865] FileSystemProvider - Path traversal via PSRP filenames in Copy-Item -FromSession](https://dev.azure.com/msazure/One/_workitems/edit/38762093/) `Copy-Item -FromSession` builds local destination paths from item, directory, and alternate-data-stream names returned by the remote PSRP endpoint without validating them. A malicious or compromised endpoint can return a name containing "".."", a path separator, a drive/root, or "":"" to write files outside the user-selected -Destination (for example the Startup folder or a PowerShell profile), yielding arbitrary file write and code execution in the client user's context This pull request prevents path traversal attacks for `Copy-Item -FromSession`. It introduces validation to ensure that remote-supplied file, directory, and alternate data stream names cannot be used to escape intended directories. **Security improvements for remote copy operations:** * Added a new method `CanRemoteNameCausePathTraversal` in `FileSystemProvider.cs` to detect potentially dangerous remote-supplied names that could enable path traversal. * Updated `CopyDirectoryFromRemoteSession` and `CopyFileFromRemoteSession` methods to validate remote directory, file, and alternate data stream names using the new method, and to throw descriptive errors if an unsafe name is detected. * Added new error messages to `FileSystemProviderStrings.resx` for directory, file, and alternate data stream path traversal attempts. **Testing enhancements:** * Introduced direct tests for `CanRemoteNameCausePathTraversal` with a variety of safe and unsafe names in `Copy-Item.Tests.ps1`. * Refactored remote session test setup. They haven't been running for PS7. This PR used a helper function and updated test tags to ensure tests run in the correct environments. Cherry picked from !41443 ---- #### AI description (iteration 1) #### PR Classification Security fix to prevent path traversal attacks in the `Copy-Item -FromSession` cmdlet. #### PR Summary This PR hardens the `Copy-Item -FromSession` cmdlet against remote path traversal vulnerabilities by validating remote file names, directory names, and alternate data stream names to prevent malicious path manipulation. - `FileSystemProvider.cs`: Added `CanRemoteNameCausePathTraversal()` method to detect path traversal characters (`\`, `/`, `:` on Windows) and patterns (`.`, `..`) in remote names, with validation checks in `CopyDirectoryFromRemoteSession()` and `CopyFileFromRemoteSession()` methods - `FileSystemProviderStrings.resx`: Added three new error message resources for directory, file, and alternate data stream path traversal violations - `Copy-Item.Tests.ps1`: Added comprehensive test cases to validate path traversal detection for various malicious and benign file name patterns across Windows and Unix platforms <!-- GitOpsUserAgent=GitOps.Apps.Server.pul...
Pester Testing Test Guide
Also see the Writing Pester Tests document.
Running Pester Tests
Go to the top level of the PowerShell repository and run: Start-PSPester
inside a self-hosted copy of PowerShell.
You can use Start-PSPester -Tests SomeTestSuite* to limit the tests run.
Testing new powershell processes
Any launch of a new powershell process must include -noprofile so that
modified user and system profiles do not causes tests to fail. You also must
take care to call the development copy of PowerShell, which is not the first
one on the path.
Example:
$powershell = Join-Path -Path $PsHome -ChildPath "pwsh"
& $powershell -noprofile -command "ExampleCommand" | Should Be "ExampleOutput"
Portability
Some tests simply must be tied to certain platforms. Use Pester's
-Skip directive on an It statement to do this. For instance to run
the test only on Windows:
It "Should do something on Windows" -Skip:($IsLinux -Or $IsMacOS) { ... }
Or only on Linux and OS X:
It "Should do something on Linux" -Skip:$IsWindows { ... }
Pending
When writing a test that should pass, but does not, please do not skip or delete
the test, but use It "Should Pass" -Pending to mark the test as pending, and
file an issue on GitHub.