Advisory Database
  • Advisories
  • Dependency Scanning
  1. pypi
  2. ›
  3. asyncssh
  4. ›
  5. CVE-2026-54591

CVE-2026-54591: asyncssh has SCP Path Traversal to Arbitrary File Write

August 26, 2026

Productasyncssh (all versions through 2.23.0)
RelatedCVE-2019-6111 (same class in OpenSSH)
FixAsyncSSH 2.23.1

A malicious SSH server can write arbitrary files on the asyncssh SCP client’s filesystem by sending filenames containing ../ traversal sequences. The SCP receive path does not currently sanitize server-provided filenames. By chaining directory traversals via the D (directory) action, an attacker can escape any target directory and overwrite ~/.bashrc, ~/.ssh/rc, or ~/.ssh/authorized_keys, achieving code execution. This is the same vulnerability class as CVE-2019-6111. The mitigation applied in OpenSSH does not appear to have been adopted in asyncssh.


Steps to exploit:

Step 1 - Normal usage: Application calls await asyncssh.scp((conn, 'file'), '/home/user/downloads/'). This is the standard, documented API.

Step 2 - SCP protocol: asyncssh opens an SSH exec channel, runs scp -f file. The server controls the filename field:

C0644 100 ../pwned.txt\n       (simple traversal)

D0755 0 ..\n                   (traverse up, repeat as needed)
C0644 47 .bashrc\n             (write payload)
E\n

Step 3 - _parse_cd_args (scp.py:134-142) returns the filename verbatim:

def _parse_cd_args(args: bytes) -> Tuple[int, int, bytes]:
permissions, size, name = args.split(None, 2)
return int(permissions, 8), int(size), name  # no sanitization

The returned name is not passed through basename() and is not checked for .. or / components.

Step 4 - _recv_files (scp.py:706-713) joins the unsanitized name:

new_dstpath = posixpath.join(dstpath, name)

With dstpath=b'/home/user/downloads/subdir' and name=b'../pwned.txt', this resolves to /home/user/downloads/pwned.txt, outside the target.

Step 5 - File write: _recv_file opens the traversed path via self._fs.open(dstpath, 'wb') and writes attacker-controlled content. The resolved path is not checked against the target directory boundary.

Step 6 - RCE chains:

TargetExecution triggerReliability
~/.bashrcNext terminal openHigh
~/.profileNext loginHigh
~/.ssh/rcNext SSH connection (requires sshd)High
~/.ssh/authorized_keysAttacker logs in with command=Medium

Reproduction:

Link to reproduction script: path_traversal_poc.zip

docker build -t asyncssh-scp-traversal -f Dockerfile .
docker run --rm asyncssh-scp-traversal

The attached poc_scp_traversal.py starts a malicious SSH server in-process using asyncssh’s own API, then downloads from it via asyncssh.scp().

Expected Output:

References

  • github.com/advisories/GHSA-2wxc-x7rj-hg8f
  • github.com/ronf/asyncssh/commit/d730803b8e4e94c20c7580d90f94d1e05f9f58de
  • github.com/ronf/asyncssh/releases/tag/v2.23.1
  • github.com/ronf/asyncssh/security/advisories/GHSA-2wxc-x7rj-hg8f
  • nvd.nist.gov/vuln/detail/CVE-2026-54591

Code Behaviors & Features

Detect and mitigate CVE-2026-54591 with GitLab Dependency Scanning

Secure your software supply chain by verifying that all open source dependencies used in your projects contain no disclosed vulnerabilities. Dependency Scanning using SBOM also detects vulnerabilities from proprietary advisories that this site does not include. Learn more about Dependency Scanning using SBOM →

Affected versions

All versions before 2.23.1

Fixed versions

  • 2.23.1

Solution

Upgrade to version 2.23.1 or above.

Impact 8.1 HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H

Learn more about CVSS

Weakness

  • CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

Source file

pypi/asyncssh/CVE-2026-54591.yml

Spotted a mistake? Edit the file on GitLab.

  • Site Repo
  • About GitLab
  • Terms
  • Privacy Statement
  • Contact

Page generated Sun, 08 Nov 2026 00:16:26 +0000.