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

CVE-2026-45309: AsyncSSH Path Traversal Vulnerability

CVE-2026-45309 is a path traversal flaw in AsyncSSH that allows attackers to bypass authentication using malicious usernames. This post explains the technical details, affected versions, and mitigation steps.

Published:

CVE-2026-45309 Overview

CVE-2026-45309 is a path traversal vulnerability [CWE-22] in AsyncSSH, a Python package providing an asynchronous SSHv2 client and server implementation built on the Python asyncio framework. Versions prior to 2.23.0 expand the OpenSSH-compatible AuthorizedKeysFile %u token with the raw SSH username during pre-authentication server config reload. An attacker can supply a username containing /, \, or .. path traversal segments to redirect the authorized-keys lookup outside the intended directory. The attacker can then authenticate with a key file of their choosing. The issue is fixed in AsyncSSH 2.23.0.

Critical Impact

Remote attackers can bypass SSH authentication on servers configured with AuthorizedKeysFile authorized_keys/%u by supplying a crafted username that traverses to an attacker-controlled key file.

Affected Products

  • AsyncSSH Python package versions prior to 2.23.0
  • SSH server deployments using AuthorizedKeysFile templates that include the %u token
  • Applications embedding AsyncSSH server functionality with per-user authorized key file layouts

Discovery Timeline

  • 2026-07-17 - CVE-2026-45309 published to NVD
  • 2026-07-23 - Last updated in NVD database

Technical Details for CVE-2026-45309

Vulnerability Analysis

AsyncSSH mirrors OpenSSH configuration semantics, including token substitution inside AuthorizedKeysFile. The %u token is intended to expand to the authenticating user's name, producing a per-user path such as authorized_keys/alice. AsyncSSH performs this substitution in asyncssh/config.py, asyncssh/connection.py, asyncssh/auth_keys.py, and asyncssh/misc.py during pre-authentication server config reload. The substitution uses the raw username string without validating for path separators, drive letters, or parent-directory segments. As a result, the resolved file path can escape the intended directory when the SSH client presents a specially crafted username.

Root Cause

The underlying defect is missing input validation on the SSH username before it is interpolated into a filesystem path [CWE-22]. Because token expansion happens prior to authentication, the server trusts an attacker-supplied identifier to compose a security-critical file lookup. Usernames containing /, \, .., or Windows drive prefixes such as C: are treated as legitimate path fragments.

Attack Vector

An unauthenticated remote attacker connects to a vulnerable AsyncSSH server and presents a username such as ../../tmp/attacker. The server expands AuthorizedKeysFile authorized_keys/%u into a path outside the intended directory. If the attacker can place a public key file at that resolved location, either through a separate write primitive, a shared filesystem, or a world-writable directory, they can then authenticate using the matching private key.

python
# Security patch in asyncssh/config.py
# Source: https://github.com/ronf/asyncssh/commit/3d515ba9ba0cd9990d248bdf62bcf05d51261a88

_token_pattern = re.compile(r'%(.)')
_env_pattern = re.compile(r'\${(.*?)}')
_unsafe_user_pattern = re.compile(r'^\.\.$|^~|^[A-Za-z]:|[/\\]|\$\{.*?\}')

The added _unsafe_user_pattern regex rejects usernames that are .., begin with ~ or a drive letter, contain forward or backward slashes, or embed environment variable references. A companion commit introduced the IllegalUserName exception surfaced during unsafe substitution.

Detection Methods for CVE-2026-45309

Indicators of Compromise

  • SSH authentication log entries containing usernames with /, \, .., ~, or drive letter prefixes such as C:
  • Successful authentications for users that do not exist in the system identity store
  • Access to authorized_keys files located outside the configured base directory
  • Unexpected reads of files whose paths resolve above the AsyncSSH working directory

Detection Strategies

  • Inspect AsyncSSH server logs for pre-authentication username strings containing path traversal characters and alert on any non-alphanumeric username tokens.
  • Enable filesystem auditing on the directory referenced by AuthorizedKeysFile and generate alerts for reads originating from the AsyncSSH process that resolve outside that directory.
  • Correlate successful public-key authentications with the resolved key file path to identify lookups that escape the intended per-user layout.

Monitoring Recommendations

  • Ship AsyncSSH connection logs to a centralized logging pipeline and apply detections for suspicious username patterns.
  • Track the installed AsyncSSH package version across Python environments and flag any host running a release earlier than 2.23.0.
  • Monitor for new or modified authorized_keys files appearing in unexpected filesystem locations that could be staged for exploitation.

How to Mitigate CVE-2026-45309

Immediate Actions Required

  • Upgrade AsyncSSH to version 2.23.0 or later in every Python environment that hosts an SSH server.
  • Audit AsyncSSH server configurations for AuthorizedKeysFile directives containing the %u token and confirm they resolve only within an intended directory.
  • Review recent SSH authentication logs for usernames containing path traversal characters and rotate any keys associated with suspicious sessions.

Patch Information

The fix is available in AsyncSSH 2.23.0. Two commits address the issue: commit 2af2382 introduces the IllegalUserName exception for unsafe user substitutions, and commit 3d515ba expands the unsafe username regex to cover slashes, drive letters, tilde prefixes, and embedded environment expansions. See the GitHub Security Advisory GHSA-g794-3fmp-753h for the full advisory.

Workarounds

  • Remove the %u token from AuthorizedKeysFile and use a single shared authorized keys file with per-key restrictions until the upgrade is complete.
  • Enforce a strict username allowlist in an upstream layer, rejecting any connection whose username contains characters outside [A-Za-z0-9_-].
  • Run the AsyncSSH server under a dedicated unprivileged account with filesystem access restricted to the intended authorized-keys directory to limit the reach of traversal attempts.
bash
# Configuration example: upgrade AsyncSSH and validate the installed version
pip install --upgrade 'asyncssh>=2.23.0'
python -c "import asyncssh; print(asyncssh.__version__)"

# Safer AuthorizedKeysFile layout without the %u token
# AuthorizedKeysFile /etc/asyncssh/authorized_keys

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.