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. Learn more about Dependency Scanning →

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 Tue, 22 Sep 2026 12:20:41 +0000.