Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-48798

CVE-2026-48798: SSH.NET Path Traversal Vulnerability

CVE-2026-48798 is a path traversal vulnerability in SSH.NET library that allows malicious servers to write files outside intended directories. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-48798 Overview

CVE-2026-48798 is a path traversal vulnerability [CWE-22] in SSH.NET, a Secure Shell (SSH) library for .NET. The ScpClient.Download(string directoryName, DirectoryInfo directoryInfo) method trusts file and directory names returned by the remote SCP server and combines them with the requested local directory without containment validation. A malicious, compromised, or man-in-the-middle SCP server can supply ../ sequences or absolute paths to write files outside the intended download directory. The affected code path exists in SSH.NET version 2025.1.0 and earlier and is fixed in version 2026.0.0.

Critical Impact

A hostile SCP server can create or overwrite arbitrary files anywhere the client process has write permission, enabling code execution through configuration or startup file overwrite.

Affected Products

  • SSH.NET library versions up to and including 2025.1.0
  • .NET applications invoking ScpClient.Download(string, DirectoryInfo) for recursive SCP downloads
  • Any client connecting to untrusted or attacker-controlled SCP servers using SSH.NET

Discovery Timeline

  • 2026-08-18 - CVE-2026-48798 published to NVD
  • 2026-08-18 - Last updated in NVD database

Technical Details for CVE-2026-48798

Vulnerability Analysis

SSH.NET implements recursive SCP downloads by parsing the SCP protocol messages that the remote server sends. Each C (file) or D (directory) command from the server includes a name that the client uses to construct a local path. In vulnerable versions, ScpClient.Download concatenates the server-supplied name onto the local target directory without verifying that the resulting path remains inside that directory.

Because the client trusts server-controlled input, a name such as ../../etc/cron.d/payload or an absolute path like /home/user/.ssh/authorized_keys will resolve outside the intended containment root. Exploitation requires the user to initiate a download, satisfying the user-interaction requirement, but the attacker controls the number, names, and contents of files delivered in a single recursive download session.

Write primitives from this class of flaw commonly lead to code execution when an attacker overwrites startup scripts, scheduled task files, SSH authorized_keys, or application configuration files consumed by the client process.

Root Cause

The root cause is missing path containment validation on untrusted input crossing a trust boundary. ScpClient treated the SCP server as authoritative for filenames and directory names and did not canonicalize the constructed local path or reject names containing directory separators, .. components, or drive/root prefixes.

Attack Vector

The attack requires a client using SSH.NET to perform a recursive SCP download against an attacker-controlled or man-in-the-middle SCP server. The server responds to the download with crafted C/D protocol records containing traversal sequences or absolute paths. The client writes each file to the attacker-chosen location using the privileges of the client process.

text
// Patch excerpt from src/Renci.SshNet/ScpClient.cs
 private static readonly byte[] SuccessConfirmationCode = { 0 };
 private static readonly byte[] ErrorConfirmationCode = { 1 };

+ private static readonly char[] InvalidLocalNameChars = Path.GetInvalidFileNameChars();
+
 private IRemotePathTransformation _remotePathTransformation;
 private TimeSpan _operationTimeout;
// Source: https://github.com/sshnet/SSH.NET/commit/600be0de543765995a189b5d7cd4efac5007f3ce

The fix introduces InvalidLocalNameChars derived from Path.GetInvalidFileNameChars() and uses it to reject server-supplied names that contain path separators or other invalid characters before joining them with the local directory.

Detection Methods for CVE-2026-48798

Indicators of Compromise

  • Files created outside the target download directory following an SCP recursive download by a .NET application.
  • Unexpected modifications to sensitive files such as ~/.ssh/authorized_keys, /etc/cron.d/*, Windows Startup folder entries, or application configuration files after an SCP session.
  • SSH.NET assemblies (Renci.SshNet.dll) with file versions at or below 2025.1.0 deployed in production applications.

Detection Strategies

  • Inventory .NET applications and identify dependencies on Renci.SshNet with version <= 2025.1.0 using SBOM tooling or dotnet list package --vulnerable.
  • Static analysis for call sites of ScpClient.Download(string, DirectoryInfo) and review whether the remote endpoint is trusted and authenticated with strict host key verification.
  • File integrity monitoring on directories writable by service accounts that run SSH.NET-based clients to detect writes outside expected download roots.

Monitoring Recommendations

  • Log the full local path of every file written during SCP downloads and alert on paths that escape the requested destination directory.
  • Monitor process telemetry for .NET processes writing to autostart locations, credential files, or scheduler directories shortly after outbound SSH connections.
  • Alert on outbound SSH connections from application servers to unexpected SCP endpoints, especially where host key pinning is not enforced.

How to Mitigate CVE-2026-48798

Immediate Actions Required

  • Upgrade the SSH.NET NuGet package to version 2026.0.0 or later in all affected applications and redeploy.
  • Audit code for uses of ScpClient.Download(string directoryName, DirectoryInfo directoryInfo) and confirm the destination directory is on a filesystem where a traversal write would not be catastrophic until the patch is deployed.
  • Restrict SCP client processes to least-privilege service accounts that cannot write to system, startup, or credential locations.

Patch Information

The fix is available in SSH.NET 2026.0.0. Review the GitHub Security Advisory GHSA-q939-rpr3-3284, the GitHub Release 2026.0.0, and the patch commit 600be0de5437 for details.

Workarounds

  • Replace recursive ScpClient.Download calls with per-file downloads where the client controls the target filename, ignoring server-supplied names.
  • Perform SCP downloads into an isolated staging directory on a dedicated volume, then validate resolved paths against the staging root before moving files to their final location.
  • Enforce strict SSH host key verification and disable fallback to unknown hosts to reduce exposure to man-in-the-middle SCP servers.
bash
# Upgrade SSH.NET to the patched release
dotnet add package SSH.NET --version 2026.0.0
dotnet restore
dotnet build -c Release

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.