Update dependency asyncssh to v2.23.1 [SECURITY] - #117
Open
renovate[bot] wants to merge 1 commit into
Open
Conversation
renovate
Bot
force-pushed
the
renovate/pypi-asyncssh-vulnerability
branch
from
June 12, 2026 13:46
303decb to
e0ab633
Compare
renovate
Bot
force-pushed
the
renovate/pypi-asyncssh-vulnerability
branch
2 times, most recently
from
August 1, 2026 08:05
0f46af6 to
eda0d27
Compare
renovate
Bot
force-pushed
the
renovate/pypi-asyncssh-vulnerability
branch
from
August 29, 2026 12:11
eda0d27 to
69dd1cf
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
2.22.0→2.23.1AsyncSSH
AuthorizedKeysFile %upath traversal allows attacker-selected authorized keys to authenticate a traversal usernameCVE-2026-45309 / GHSA-g794-3fmp-753h
More information
Details
Summary
AsyncSSH 2.22.0 expands the OpenSSH-compatible
AuthorizedKeysFile%utoken with the raw SSH username during pre-authentication server config reload. A server configured with a documented per-user key pattern such asAuthorizedKeysFile authorized_keys/%ucan be made to read an authorized-keys file outside the intended directory when the SSH username contains path traversal segments. If the attacker can place or reference a readable authorized-keys-format file containing their public key, the attacker can authenticate over SSH as the traversal username.Affected Product
v2.22.0, commitaf5a81e669633d83d535163f93b6bf3f957c9238c3ce72b01be4f97b40e62844dd384227e5ff5a401a3793007c42f86a5c8eb537Vulnerability Details
asyncssh/config.py,asyncssh/connection.py,asyncssh/auth_keys.py,asyncssh/misc.py)%uinAuthorizedKeysFileis expanded from the remote username without rejecting path separators or..segments, and the resulting path is opened without constraining it to the intended authorized-keys directory.Attack Preconditions
AuthorizedKeysFilecontains%u, for exampleAuthorizedKeysFile authorized_keys/%u./,\, or..before AsyncSSH uses the username for key-file selection.Reproduction
The run-scoped evidence contains a safe localhost proof:
Start the proof harness saved at
harness_app.py
Run
exploit_proof.py
through
run_proof.sh
The harness creates
sshd_configwithAuthorizedKeysFile authorized_keys/%u, writes the attacker's public key to a file outsideauthorized_keys/, starts a real AsyncSSH server, and attempts two SSH logins.Expected result: the normal username
victimfails, while the traversal username authenticates with the same attacker key.Observed proof output:
Severity
CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N/E:PReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
asyncssh has an incomplete fix for CVE-2026-45309 — AuthorizedKeysFile %u still escapes the intended directory via a leading ~ (and weakly via ${ENV}) username substitution
CVE-2026-54590 / GHSA-qr67-gv47-xwwh
More information
Details
Incomplete fix for CVE-2026-45309 (GHSA-g794-3fmp-753h). The
2.23.0 guard that sanitises the SSH username before
%usubstitutionin
AuthorizedKeysFileblocks/,\and.., but does not block aleading
~(or${ENV}), both of which are re-introduced by laterexpansion and reach the file open — defeating the guard.
Affected: asyncssh 2.23.0 and current
develop(commita60f863,HEAD on 2026-05-29).
Summary
The fix for CVE-2026-45309 added a guard in
SSHServerConfig._set_tokens(asyncssh/config.py:715-716) thatrejects an SSH username containing
/,\, or equal to.., beforeit is substituted for the
%utoken inAuthorizedKeysFile:However, the
%u-substituted value is subsequently passed throughenvironment-variable expansion (
_expand_val,config.py:145-149—token expansion then env expansion) and, at file-open time, through
expanduser()(read_authorized_keys→read_file→open(Path(filename).expanduser()),auth_keys.py:348→misc.py:290). Both re-introduce the path control the guard was meantto remove, so a username that contains no
//\can still cause theserver to read an authorized-keys file outside the intended per-user
directory.
The client-supplied username reaches this path pre-authentication:
_process_userauth_requesttakes the username from theSSH_MSG_USERAUTH_REQUESTpacket (connection.py:2516-2519) and_finish_userauthcallsreload_config()(connection.py:2536),which re-evaluates
AuthorizedKeysFilewithusername=self._username(
connection.py:5906) before the offered key is validated.Primary vector — leading
~A username such as
~rootor~victimpasses the guard (no/). Fora server whose
AuthorizedKeysFilebegins with%u— e.g.AuthorizedKeysFile %u/.ssh/authorized_keys— the expanded value is~victim/.ssh/authorized_keys, whichexpanduser()resolves to/home/victim/.ssh/authorized_keys(~root→/root/...; a bare~→ the server process's home). The username has therefore escaped the
intended per-user location without using any path separator —
defeating the purpose of the guard.
Note:
expanduser()only expands a leading~, so this vectorrequires
%uto be the first path component ofAuthorizedKeysFile.(The CVE-2026-45309
authorized_keys/%uexample —%unot leading —is not reachable this way; that was the
../form.)Impact and limitations
a60f863): the guard isbypassable and the authorized-keys lookup is redirected to an
attacker-named home tree, pre-auth, with a separator-free username.
redirected username when a readable authorized-keys file containing
the attacker's key is reachable at the redirected location. The parent
CVE accepted this exact precondition and was scored
C:N/I:H/A:N;this is scored consistently.
the path-redirection mechanism in-process, deterministically. No new
primitive is claimed beyond the parent CVE's accepted model — only
that the 2.23.0 fix does not close it for
~/${ENV}.%umust be the leading pathcomponent; on Python 3.13,
Path('~nonexistentuser').expanduser()raises
RuntimeError, so only existing accounts are reachable(confirmed: asyncssh 2.23.0, Python 3.13.12).
Secondary vector —
${ENV}(defense-in-depth only)A username like
${HOME}also passes the guard and is thenenvironment-expanded, re-introducing
/. Weaker and not a practicalexploit: the attacker can only reference env vars that already exist
in the server process (a missing variable raises
ConfigParseError)and cannot control their values. Reported as hardening.
Reproduction
In-process, deterministic, no network. Against a checkout of asyncssh
2.23.0:
Output (abridged):
Suggested fix
Tighten
_set_tokensto also reject usernames that re-introduce pathcontrol after expansion — reject a leading
~/~userand$/${references in
self._user. More robustly, validate that the FINALexpanded
AuthorizedKeysFilepath remains within the intended basedirectory, and/or suppress
expanduser/environment expansion on the%u-derived component specifically.Disclosure
Coordinated, ~90-day default. I will not publish details/PoC before a
fix is released, and am happy to validate the patch. Credit (if given)
to
cesabici-bit.PoC source
(see code block below)
Severity
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Release Notes
ronf/asyncssh (asyncssh)
v2.23.1Compare Source
v2.23.0Compare Source
Configuration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.