WEDNESDAY, OCTOBER 7, 2026|No. 17730
Technology · Software Release

OpenSSH Releases Version 10.6 with Focus on Security and Faster Bug Fixes

OpenSSH has launched version 10.6, introducing security enhancements and a new release cadence aimed at delivering bug fixes more rapidly to users.

The OpenSSH logo displayed on a digital interface.
The OpenSSH logo displayed on a digital interface. · Photo by FlyD on Unsplash
1 sources
Pipeline ingest
3 reads
Positive / Neutral / Negative
0 countries
Related coverage

Open SSH Release Notes


OpenSSH 10.6/ 10.6p1 (2026-10-06)

OpenSSH 10.6 was released on 2026-10-06. It is available from the
mirrors listed at https://www.openssh.com/.
OpenSSH is a 100% complete SSH protocol 2.0 implementation and
includes sftp client and server support.

Recently the OpenSSH team have received a large number of security
bug reports, many of which are findings from AI models or made with
AI assistance. While many AI reports are determined not to have
security impact when considered in the context of a realistic
threat model, we very much welcome these reports, especially when
combined with human triage, analysis, test-cases and particularly
when accompanied by proposed fixes.

** We have seen a number of cases where a security bug identified
** by AI tools is subsequently independently discovered by a
** different researcher. This suggests that adversaries who do not
** report bugs to OSS projects are likely to be able to discover
** these bugs too. Given this, the OpenSSH team will, for now, be
** making more frequent releases to get bugfixes into users' hands
** more quickly rather than batching them until the next planned
** release.

Once again, we would like to thank the OpenSSH community for their
continued support of the project, especially those who contributed
code or patches, reported bugs, tested snapshots or donated to the
project. More information on donations may be found at:
https://www.openssh.com/donations.html

Future deprecation notice
-------------------------

 * scp(1): begin deprecating the -R flag, which is used to perform a
 remote-to-remote copy by executing scp on a remote host. This
 option is a fragile optimisation that is difficult to use because
 it requires credentials on the remote host. It also creates
 security risks if the shell quoting rules on the remote system
 where the copy is performed differ from the client's expectations.

 From OpenSSH 10.6, this option will continue to work but will
 cause a deprecation warning to be emitted to standard error. In
 a future release, the option will be ignored and will leave in
 place the default remote-to-remote copy behaviour (copy via the
 host running scp).

 * sshd(8): support for platforms that do not allow file descriptor
 passing and that also require root privilege for PTY allocation
 will be removed in a future release. Affected platforms are known
 to include SCO OpenServer 5 and QNX 6 but may include other
 similarly old operating systems. This deprecation can be avoided
 if the user community for these platforms is able to assist us in
 building alternatives, such as avoiding the need for root in PTY
 allocation.

Potentially-incompatible changes
--------------------------------

 * ssh(1), sshd(8): compression will be less effective as a result
 of the change noted below in the "Security" section

 * ssh(1): destination usernames entered on the commandline are now
 more strictly checked and will refuse usernames that include
 backslash and dollar symbols. Usernames that are specified by
 the "User" directive in configuration files are not subject to
 these restrictions. The motivation for this change is mentioned
 below in the "Security" section.

 * sshd(8): on platforms that do not support file descriptor passing
 and that require root for PTY allocation, the GatewayPorts and
 StreamLocalForwarding options are forcibly disabled. The
 motivation for this change is discussed below in the "Security"
 section.

Changes since OpenSSH 10.5
==========================

This release contains a number of security fixes, several new
features and some small bugfixes.

Security
========

 * sftp(1): more strictly validate paths returned from the server to
 avoid some cases where a server could return paths that could
 manipulate a recursive copy operation into writing outside its
 target directory. Report and patch from Junghoon Cho.

 * sshd(8): when GSSAPIAuthentication is in use, only store GSSAPI
 credentials when authentication has succeeded. Avoids a situation
 where credentials from a failed GSSAPIAuthentication attempt may
 persist and be made inappropriately available if another
 authentication subsequently succeeds. Issue report and patch from
 Moritz Theile.

 * sshd(8): reset GSSAPIAuthentication before authentication, avoiding
 state from one authentication attempt being confused with that of
 a later attempt. Report and feedback from Moritz Theile.

 * sshd(8), ssh(1): disable LZ77 dictionary coder to mitigate the
 side-channel leaks described in "Crossing the Streams: SSH
 Plaintext Recovery via a Common Compression Context in
 Multiplexed Channels" by Fabian Bäumer and Marcus Brinkmann,
 preprint https://arxiv.org/abs/2609.07709 (2026)

 A chosen-plaintext attack method exists which makes use of
 dictionary-based compression to recover secrets from one channel
 by interacting with the SSH session's shared compression
 dictionary through another channel.

 Attacker-controlled input can recognizably reflect into the
 total length of transmitted ciphertexts by virtue of LZ77
 replacing repeated strings with back-references into the SSH
 session's encoder search buffer, which is shared across all
 channels. For this reason, the documentation already recommended
 against enabling compression for connections that share trusted
 and untrusted traffic.

 This change will reduce the effectiveness of the Compression
 option. Users are encouraged to use application-level compression
 over the SSH protocol where possible, as this will typically be
 more effective and will be completely immune to this type of
 attack.

 * ssh(1): disallow '$' and '\' characters in usernames entered on
 the command-line to avoid usernames from untrusted sources
 yielding injection in shell context via ProxyCommand, Match exec, etc.
 Usernames specified via the configuration files are not subject
 this this control. Reported by SecBuddyF KeenLab Tencent
 (CodeBuddy Security)

 We continue to recommend against directly exposing ssh(1) and
 other tools' command-lines to untrusted input. Mitigations such
 as this can not be absolute given the variety of shells and user
 configurations in use.

 * ssh-keygen(1): correct handling of Daylight Saving Time when
 converting dates. Previous handling could cause errors of
 up to +/- 1 hour (unless you are in the Antarctica/Troll
 timezone, where the error could be +/- 2 hours). These errors
 could result in creation of certificates with incorrect expiry
 times. bz4004; from Khush Patel

 * sshd(8), ssh(1): ensure that compressed payloads don't inflate
 past the maximum supported packet length. Reported by Oleh Konko.

 * sshd(8): fully honor the authorized_keys "restrict" keyword,
 which was not being properly applied to tunnel forwarding
 (PermitTunnel, disabled by default). This is a separate problem
 to the one fixed in openssh-10.5.

 * sshd(8): correctly handle some options that accept "none". Some
 options, including AuthorizedPrincipalsFile, were documented as
 accepting "none" as a way to disable them; however, when
 overridden by an sshd_config(5) Match keyword, this argument was
 being incorrectly interpreted as a literal file.
 With Chris Rohlf in collaboration with Claude and Anthropic Research

 * sshd(8): On OS X SDK >= 27, sandboxing is no longer supported
 as the API we depended upon has been removed and no obvious
 alternative provided.

 * sshd(8): on platforms that do not support file descriptor passing
 and that require root for PTY allocation, the post-authentication
 sshd-session process retains root privilege, whereas on other
 platforms this process runs with the privilege of the logged-in
 user. When sshd-session was run with elevated privilege, it could
 perform certain actions as root and circumvent controls that
 would normally have applied to the user, such as making unix
 domain socket connections or binding (via -R forwarding) to low-
 numbered TCP ports.

 For this reason, this release disables the GatewayPorts and
 StreamLocalForwarding options and support for these (few)
 platforms will be removed in future if no alternatives to
 requiring privilege in the post-authentication process are found.
 Affected platforms include QNX 6, SCO OpenServer 5 and builds
 that were made with the --disable-fd-passing configure option.

 This problem was reported separately by sn0x-sharma and by Dark
 River.

New features
------------

 * All: enable hybrid post-quantum ssh-mldsa44-ed25519 signature
 algorithm. Note that this no longer uses the "@openssh.com"
 vendor extension suffix that the previous experimental
 implementation used. Keys generated with the previous experimental
 support must be regenerated and/or removed.

 * sshd(8): Add the WarnWeakCrypto option to sshd_config(5). This
 option was previously available for the client only. This option
 is enabled by default and will log when the client uses a key
 agreement scheme that is not post-quantum safe.

 * ssh-keygen(1), ssh-add(1): preserve user-verification (PIN or
 biometric) requirement for resident keys loaded from a FIDO
 token, by checking the credential's credProtect policy.
 GHPR701 from Savely Krasovsky

 * ssh(1): include local and remote version strings in the ~I
 connection information display.

 * ssh-add(1): add a -P flag to skip PIN entry for FIDO and PKCS#11
 tokens that do not require it.

 * sftp(1): add '-p' flag for mkdir/lmkdir to create directories as
 required. This flag has similar ergonomics to mkdir(1), and
 previously-existing directories do not cause an error.

 * ssh-keygen(1): add a "hexdump" key export mode that dumps the SSH
 wire-formatted key blob in hex format. Useful when writing
 documentation, tests, etc. E.g. `ssh-keygen -em hexdump -f /key`

 * ssh(1), sshd(8): ChannelTimeout now accepts timeouts with
 fractional seconds.

 * sshd(8): allow specification of the location of $SSH_AUTH_SOCK
 used for agent forwarding using a new AgentSocketPath option.
 This supports both using a user-specific path, such as the
 default of a subdirectory of $HOME ("user:.ssh/agent"), and
 the previous approach of allowing agent forwarding sockets to be
 located in a shared directory (e.g. "shared:/tmp"). Sockets
 created in shared directories will be created inside a
 subdirectory with a randomised name. bz3860

 * ssh-agent(1): allow specification of agent socket directories
 using a -A flag. It accepts "user:" and "shared:" directory
 styles similar to the sshd AgentSocketPath option.

 * sshd(8): account for public key authentication "key ok" tests
 separately to auth attempts. Add a `PubkeyOptions max-pk-ok:nnnn`
 option to allow a number of PK_OK tests (asking whether the
 server might accept a given public key) that do not count against
 MaxAuthTries, defaulting to 6 attempts. After these attempts are
 exhausted, further attempts count as failed authentications
 against MaxAuthTries. Practically, this allows more keys on disk
 or held in ssh-agent to be checked for use before the server
 disconnects.

 * ssh(1), sshd(8): extend the existing TCPKeepAlive option to also
 support setting keepalives on sockets created for forwarding
 connections. Previously this option controlled keepalives on the
 connection socket only. TCPKeepAlive "yes" or "transport" enables
 keepalives on the connection socket. "TCPKeepAlive all" additionally
 enables them for forwarding sockets. bz3921

Bugfixes
--------

 * sshd(8), ssh(1): fix configuration matching on more Turkic
 languages which have disjoint dotted and dotless i/I characters,
 specifically Azerbaijani and Crimean Tatar. bz3991

 * ssh(1), sshd(8): don't attempt to set TCP_NODELAY on non-IP/IPv6
 sockets. Eliminates some noise in debug logs.

 * ssh(1): fix case for ssh -G option output; bz4005

 * ssh(1), sshd(8): Fix ChannelTimeout specificity; previously a
 more specific channel type (e.g. "session:shell") could clobber
 a user-specified ChannelTimeout if it was less specific (e.g.
 "session"). Also, in some cases, the debug messages were
 printing 0 instead of the effective timeout. bz3994

 * sftp(1): avoid NULL dereference crash in some circumstances when
 a server fails a stat/lstat operation. GHPR707

 * sshd(8): close a race condition where a SIGTERM/SIGQUIT would be
 ignored if it was received by the server while it was processing a
 SIGHUP restart request. bz3981

 * sshd(8), ssh(1): check key and CA signature types during key
 parsing against allowlists (PubkeyAcceptedAlgorithms, etc) as
 early as possible. This reduces the attack surface presented by
 disabled algorithms. Suggested by and with extensive feedback
 from Chris Rohlf in collaboration with Claude and Anthropic
 Research.

 * All: switch the fallback implementation of the ed25519 signature
 algorithm used when libcrypto is disabled from SUPERCOP ed25519
 to libsodium. The libsodium implementation includes a number of
 strictness checks over the original reference implementation we
 have used to this point and a more ergonomic API.

 * ssh-add(1), ssh(1), ssh-keygen(1): fix spin on password entry when
 the program attempting to read a password was started in a
 background process group, with no TTY and with certain signals
 ignored. bz3995

 * scp(1): disallow nul byte in received scp -O filename. This was
 not reachable in normal operation. Reported by Chua Wei Xun.

 * ssh-keygen(1), ssh(1), sshd(8): implement a maximum number of KDF
 rounds that will be accepted when writing an OpenSSH-format
 private key or when loading one. This limit is set quite high
 (1M), but ensures that a service that is passed a bad key with a
 ridiculously high number of rounds will eventually complete
 parsing it.

 * ssh-keygen(1): bump the default number of KDF rounds from 24 to
 32 (this is a linear increase, not like bcrypt(3) which is
 exponential).

 * ssh(1): make StreamLocalBindMask properly respect Host/Match
 blocks and make it first-match-wins as documented. bz4013

 * sshd(8): make StreamLocalBindMask properly first-match-wins.

Portability
-----------

 * All: remove the NetBSD BROKEN_READ_COMPARISON workaround. This
 appears to be no longer required and caused pre-auth CPU spinning.

 * sshd(8): don't link sshd against libselinux when SELinux support
 is enabled (note: this library is still linked for the sshd-auth
 and sshd-session helper binaries).

 * sshd(8): allow madvise(..., MADV_DONTNEED_LOCKED) in the seccomp
 sandbox; needed by GrapheneOS' hardened allocator. bz4001

 * sshd(8): restrict mremap(2) flags accepted by the seccomp
 sandbox. Only MREMAP_MAYMOVE is now accepted as other flags may
 have some utility in attack chains. Reported by: Mohammad Hossein
 Abedini.

 * sshd(8): allow PAMServiceName in Match (regressed in 10.4).
 During the refactor of server option parsing, the ability to set
 PAMServiceName in Match blocks was accidentally disabled.

 * sshd(8): the --disable-fd-passing configure option has been
 removed.

Checksums:
==========

 - SHA1 (openssh-10.6.tar.gz) = 096e9cd60cd08e0acacfe16b615144f8c0463da5
 - SHA256 (openssh-10.6.tar.gz) = 0lP9h9/QH3k667vqbxKhkkusc3CN5iKUiDNI9fsR06A=
 - SHA1 (openssh-10.6p1.tar.gz) = e6a34f5625e20172b214c50ebd4e0dcb4fd18013
 - SHA256 (openssh-10.6p1.tar.gz) = qdyVZd/+hkD2TYY80poyvEo9vewFZqf8RMXW7nZ9Xzk=

Please note that the SHA256 signatures are base64 encoded and not
hexadecimal (which is the default for most checksum tools). The PGP
key used to sign the releases is available from the mirror sites:
https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/RELEASE_KEY.asc

Reporting Bugs:
===============

- Please read https://www.openssh.com/report.html
 Security bugs should be reported directly to openssh@openssh.com

OpenSSH 10.5/ 10.5p1 (2026-08-11)

OpenSSH 10.5 was released on 2026-08-11. It is available from the
mirrors listed at https://www.openssh.com/.
OpenSSH is a 100% complete SSH protocol 2.0 implementation and
includes sftp client and server support.

Recently the OpenSSH team have received a large number of security
bug reports, many of which are findings from AI models or made with
AI assistance. While many AI reports are determined not to have
security impact when considered in the context of a realistic
threat model, we very much welcome these reports, especially when
combined with human triage, analysis, test-cases and particularly
when accompanied by proposed fixes.

We have seen a number of cases where a security bug identified by
AI tools is subsequently independently discovered by a different
researcher. This suggests that adversaries who do not report bugs
to OSS projects are likely to be able to discover these bugs too.
Given this, the OpenSSH team will, for now, be making more frequent
releases to get bugfixes into users' hands more quickly rather than
batching them until the next planned release.

Once again, we would like to thank the OpenSSH community for their
continued support of the project, especially those who contributed
code or patches, reported bugs, tested snapshots or donated to the
project. More information on donations may be found at:
https://www.openssh.com/donations.html

Potentially-incompatible changes
--------------------------------

 * Portable OpenSSH now requires ECC (Elliptic Curve Cryptography)
 support in libcrypto, including support for the NISTP521 curve.
 ECC is included in the default build configurations of all
 versions of all libcrypto implementations currently supported by
 OpenSSH, including LibreSSL, OpenSSL, BoringSSL and AWS LC.
 The --without-openssl build configuration is not affected.

Changes since OpenSSH 10.4
==========================

This release contains a number of security fixes and small bugfixes.

Security
========

 * ssh-agent(1): fix an interaction between agent locking and the
 session-bind@openssh.com extension that is used to identify
 forwarded agents. These binding requests were refused when the
 agent was locked, with the result that operations that were
 intended to be limited to local use only could be performed
 remotely, including the ability to add PKCS#11 tokens and make
 use of keys that had destination restrictions applied.
 Reported by sn0x-sharma

 * ssh(1): avoid potential realloc use-after-free in the client if a
 remote forwarding is added via the local session multiplexing
 socket while a remote forwarding open request is pending with the
 server. Report and fix from Brian Mingus of Cognatory

 * sshd(8): make the authorized_keys "restrict" keyword apply
 correctly to tunnel forwarding too (which is administratively
 disabled by default). Reported by Erichen, Institute of Computing
 Technology, Chinese Academy of Sciences

New features
------------

 * ssh-keygen(1): add ability to set or clear the touch-required and
 verify-required flags on FIDO private keys when resetting a
 private key's passphrase.

 * ssh(1): tweak ordering of certificates tried during pubkey
 authentication to prefer FIDO keys that do not require user
 presence (touch) first, and FIDO keys that require user
 verification via PIN or biometrics last. This effectively tries
 low-friction authenticators before higher friction ones.

 * ssh(1): add a "ssh -Z user@host" mode that prints the keys that
 will be tried for public key authentication in the order that
 they will be used.

 * sshd(8) use setproctitle(3) to identify sshd-session when its
 acting as a post-authentication monitor.

Bugfixes
--------

 * ssh-keyscan(1): make reading the server banner a non-blocking
 operation to prevent a stuck server from blocking a many-host
 keyscan from proceeding.

 * sshd(8): use sshpkt_fatal() instead of plain fatal() for errors
 in the packet code as this provides context of the failing peer
 (address, port, user, etc).

 * sshd(8): when signing hostkey proofs for a client UpdateHostKeys
 request, allow each hostkey to perform at most one signature
 operation.

 * sshd(8) fix GSSAPI option names, that were broken during a
 servconf.c refactoring in openssh-10.4; bz3974.

 * ssh-keygen(1): pass back errors from ed25519 key generation, which
 theoretically can fail. GHPR702.

 * sshd(8): move check of public key type against allowed algorithms
 to before parsing of the key sent by the peer. This removes at
 least some key parsing and verification paths from the pre-auth
 attack surface. Suggested by Christopher Paul Rohlf of Anthropic.

 * ssh-keygen(1): fix double frees (impossible to reach outside of a
 test harness), and also use freezero where possible. From
 Christopher Paul Rohlf at Anthropic.

 * sshd(8): fix ChannelTimeout and RekeyLimit not being applied in
 sshd_config Match blocks.

 * sshd(8): in sshd config dump mode, write all directives in mixed
 case for consistency

Portability
-----------

 * sshd(8): re-allow PAMServiceName inside a Match block, which
 was incorrectly disabled during a refactoring in openssh-10.4.
 bz3987

Checksums:
==========

 - SHA1 (openssh-10.5.tar.gz) = 273163972f623bb9bffef9fd75a85c74d3b22633
 - SHA256 (openssh-10.5.tar.gz) = 9Zhp0C/mDWNLmnatq68mtbqOUhvbyYcffH04dsHUwZQ=

 - SHA1 (openssh-10.5p1.tar.gz) = 3067e2af7c526b31c7e94bc3ed38904ef791eb2c
 - SHA256 (openssh-10.5p1.tar.gz) = 1E0oqDnqna+WnMaRUP3lmRCys5Nh2tgaO9bL0ZIY2xE=

Please note that the SHA256 signatures are base64 encoded and not
hexadecimal (which is the default for most checksum tools). The PGP
key used to sign the releases is available from the mirror sites:
https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/RELEASE_KEY.asc

Reporting Bugs:
===============

- Please read https://www.openssh.com/report.html
 Security bugs should be reported directly to openssh@openssh.com

OpenSSH 10.4/ 10.4p1 (2026-07-06)

OpenSSH 10.4 was released on 2026-07-06. It is available from the
mirrors listed at https://www.openssh.com/.
OpenSSH is a 100% complete SSH protocol 2.0 implementation and
includes sftp client and server support.

Once again, we would like to thank the OpenSSH community for their
continued support of the project, especially those who contributed
code or patches, reported bugs, tested snapshots or donated to the
project. More information on donations may be found at:
https://www.openssh.com/donations.html

Potentially-incompatible changes
--------------------------------

 * sshd(8): configuration dump mode ("sshd -G") now writes directives
 in mixed case (e.g. "PubkeyAuthentication") whereas previously it
 emitted only lower-case names.

 * sshd(8): on Linux systems with the seccomp sandbox enabled,
 failures to enable SECCOMP or NO_NEW_PRIVS are now fatal.
 Previously sshd(8) would log the error but continue operation, to
 support systems that lacked these features. Now systems that
 lack these should instead disable the sandbox at configure time.

 * ssh(1), sshd(8): make the transport protocol stricter by
 disconnecting if the peer sends non-KEX messages during a post-
 authentication key re-exchange. Previously a malicious peer could
 continue sending non-key exchange messages without penalty. These
 would be buffered, causing memory to be wasted up until the
 connection terminated or the server/client hit a memory limit.
 Implementations that do not restrict messages sent during key
 exchange as per RFC4253 section 7.1 may be disconnected.
 Reported by Marko Jevtic.

Changes since OpenSSH 10.3
==========================

This release contains a number of security fixes as well as general
bugfixes and a couple of new features.

Security
========

 * sftp(1): when downloading files on the command-line using
 "sftp host:/path .", a malicious server could cause the file to
 be downloaded to an unexpected location. This issue was identified
 by the Swival Security Scanner.

 * scp(1): when copying files between two remote destinations, do
 not allow a malicious server to write files to the parent
 directory of the intended target directory. This issue was
 identified by the Swival Security Scanner.

 * sshd(8): when using the "internal-sftp" SFTP server implementation
 (this is not the default), long command lines were previously
 truncated silently after the 9th argument. If a security-relevant
 option was in the 10th or later position, it would be discarded.
 Reported by Steve Caffrey.

 * sshd(8): add a documentation note to mention that the
 GSSAPIStrictAcceptorCheck option is ineffective when the server
 is joined to a Windows Active Directory. Reported by Yarin Aharoni
 of Safebreach.

 * sshd(8): DisableForwarding=yes didn't override PermitTunnel=yes
 as it was documented to do. Note that PermitTunnel is not enabled
 by default. Reported independently by Huzaifa Sidhpurwala of
 Redhat and Marko Jevtic.

 * sshd(8): avoid a potential pre-authentication denial of service
 when GSSAPIAuthentication was enabled (this feature is off by
 default). This was not mitigated by MaxAuthTries, but would be
 penalised by PerSourcePenalties. This was reported by Manfred
 Kaiser of the milCERT AT (Austrian Ministry of Defence).

 * sshd(8): fix a number of cases where the minimum authentication
 delay was not being enforced. Reported by the Orange Cyberdefense
 Vulnerability Team.

 * ssh(1): fix a possible client-side use-after-free if the server
 changes its host key during a key reexchange. This was reported by
 Zhenpeng (Leo) Lin of Depthfirst.

New features
------------

 * All: add experimental support for a composite post-quantum
 signature scheme that combines ML-DSA 44 and Ed25519 as specified
 in draft-miller-sshm-mldsa44-ed25519-composite-sigs.

 This scheme is not enabled by default. To use it, you'll need
 to add it to HostKeyAlgorithms, PubkeyAcceptedAlgorithms, etc.
 Keys may be generated using "ssh-keygen -t mldsa44-ed25519".

 * ssh(1), sshd(8): replace the wildcard pattern matcher with an
 implementation based on an NFA. This avoids exponential worst-case
 behaviour for the old implementation.

Bugfixes
--------

 * ssh-agent(1): fix incorrect reply to "query" SSH_AGENTC_EXTENSION
 requests. bz3967

 * sshd(8): avoid sending observably different messages for valid vs
 invalid users in GSSAPIAuthentication (disabled by default).

 * ssh(1), sshd(8): fix several bugs that incorrectly
 classified bulk traffic as interactive. bz3972, bz3958

 * ssh-keygen(1), ssh-add(1): skip unsupported key types when
 downloading resident keys from a FIDO token. Previously, downloads
 would abort when one was encountered. GHPR657

 * ssh(1): fix a potential use-after-free on an error path if
 cipher_init() fails.

 * sshd(8): perform stricter encoding and validation of transport
 state passed between sshd privilege separation subprocesses. This
 somewhat further hardens the server against attacks on sshd-auth
 or sshd-session subprocesses.

 * ssh-agent(1): avoid possible runtime denial of service by
 enforcing some limits on the length of usernames in key use
 constraints.

 * sftp(1): fix two separate one-byte out-of-bounds reads, in
 SSH2_FXP_REALPATH and batch command processing.

 * sftp-server(8): disallow use of the copy-data extension to read
 and write to the same inode simultaneously.

 * ssh(1), sshd(8): avoid strlen(NULL) crash if an X11 channel was
 created before the x11-req SSH_MSG_CHANNEL_REQUEST was sent.
 GHPR679

 * sftp(1), scp(1): avoid a situation where sftp_download() could get
 stuck in a loop if a broken server repeatedly returned zero length
 while reading a file.

 * ssh(1): avoid leaking DNS0x20 case-randomised names into names
 canonicalised using CanonicalizePermittedCNAMEs. bz3966

 * sftp-server(8): avoid truncation of pathnames passed to lstat()
 during SSH_FXP_REALPATH handling on systems where PATH_MAX is not
 the actual max. GHPR688

 * ssh(1), sshd(8): correct arming of poll(2) event masks for some
 socket-type channels. GHPR660

 * sshd(8): major refactor of sshd_config parsing and management
 code, to allow for more exact serialisation/deserialisation across
 privilege separation boundaries.

 * ssh-add(1): open connection to the agent only after getopt() 
 processing has completed, to give options like "-v" a chance to
 display debug information about this operation.

 * crypto code: fix bounds checking when signing messages of length
 greater than will fit in a size_t. In OpenSSH, message sizes are
 bounded by SSHBUF_SIZE_MAX so this was unreachable.

 * crypto code: add signature malleability and pubkey validity checks
 to ed25519 verification. SSH doesn't depend on these properties

 * crypto code: fix ECDSA order check for curves with cofactor != 1.
 All supported EC curves have cofactor 1, so this was
 unreachable.

 * sshd(8): differentiate between execution failures and a subsystem
 that was not found when logging why a subsystem failed to start.
 GHPR637

 * All: use safer idioms for timegm(3) and mktime(3) error detection.

 * ssh(1), sshd(8): avoid accepting invalid cipher or MAC lists in
 config files or command-line arguments. This could cause runtime
 failures later.

 * ssh(1): fix NULL deref crash during pubkey auth when using a PEM
 style private key with no corresponding .pub key adjacent to it.

 * sshd(8): don't print an error message when trying to load a host
 private key when PKCS#11 keys are in use, as these don't need the
 private half on the filesystem. GHPR664

 * All: don't use deprecated ERR_load_crypto_strings(). GHPR650

 * ssh(1): properly report errors during configuration default
 setting. GHPR649

 * ssh(1): use correct directive name (Match instead of Host) in
 error message. bz3968

 * sftp(1): fix "ls -ln" which was not correctly showing numeric
 UID/GIDs but rather user and group names. bz3953

 * sshd(8): avoid possible NULL dereference if an allocation fails
 during config parsing. bz3948

 * All: fix ineffective guards against loading overly large public
 keys in several places. bz3969 and bz3970

 * sftp(1): ensure file descriptors used by sftp to communicate to
 its ssh(1) subprocess don't leak into executed subprocesses (e.g.
 via "!"). GHPR693

Portability
-----------

 * Sync fmt_scaled.c with OpenBSD upstream, picking up an exactness
 fix for large exponents (GHPR671)

 * sshd(8): remove duplicate sandbox entry for clock_gettime64.

 * ssh(1), sshd(8): use correct IPTOS_DSCP_VA value if not provided
 by the system headers.

 * Sync getrrsetbyname.c with OpenBSD upstream, picking up robustness
 fixes.

 * Disable replacements in openbsd-compat for strvisx(3) and
 stravis(3), as these are unused in OpenSSH

 * Avoid fortify warnings on Android bz3954

 * Fix a number of memory leaks on error paths in the portability
 code. GHPR681

 * Revise the README.privsep documentation to reflect sshd's recent
 switch to a multi-binary model.

Checksums:
==========

 - SHA1 (openssh-10.4.tar.gz) = 8502b516230865e229d55045bb4ccc67aeae905b
 - SHA256 (openssh-10.4.tar.gz) = qUVI+wMg4mVpiQbXvfMVkF3Zuyy2JrS+ZjN764mtyGE=

 - SHA1 (openssh-10.4p1.tar.gz) = ae8650a71cc52dbbd049519cee276ae6d65c2c4d
 - SHA256 (openssh-10.4p1.tar.gz) = 72Am3SrqjVYFljjV0yYpAsiSzrqfiDlYNeDQbT+2Mjg=

Please note that the SHA256 signatures are base64 encoded and not
hexadecimal (which is the default for most checksum tools). The PGP
key used to sign the releases is available from the mirror sites:
https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/RELEASE_KEY.asc

Reporting Bugs:
===============

- Please read https://www.openssh.com/report.html
 Security bugs should be reported directly to openssh@openssh.com

OpenSSH 10.3/ 10.3p1 (2026-04-02)

OpenSSH 10.3 was released on 2026-04-02. It is available from the
mirrors listed at https://www.openssh.com/.
OpenSSH is a 100% complete SSH protocol 2.0 implementation and
includes sftp client and server support.

Once again, we would like to thank the OpenSSH community for their
continued support of the project, especially those who contributed
code or patches, reported bugs, tested snapshots or donated to the
project. More information on donations may be found at:
https://www.openssh.com/donations.html

Potentially-incompatible changes
--------------------------------

 * ssh(1), sshd(8): remove bug compatibility for implementations
 that don't support rekeying. If such an implementation tries to
 interoperate with OpenSSH, it will now eventually fail when the
 transport needs rekeying.

 * sshd(8): prior to this release, a certificate that had an empty
 principals section would be treated as matching any principal
 (i.e. as a wildcard) when used via authorized_keys principals=""
 option. This was intentional, but created a surprising and
 potentially risky situation if a CA accidentally issued a
 certificate with an empty principals section: instead of being
 useless as one might expect, it could be used to authenticate as
 any user who trusted the CA via authorized_keys. [Note that this
 condition did not apply to CAs trusted via the sshd_config(5)
 TrustedUserCAKeys option.]

 This release treats an empty principals section as never matching
 any principal, and also fixes interpretation of wildcard
 characters in certificate principals. Now they are consistently
 implemented for host certificates and not supported for user
 certificates.

 * ssh(1): the -J and equivalent -oProxyJump="..." options now
 validate user and host names for ProxyJump/-J options passed
 via the command-line (no such validation is performed for this
 option in configuration files). This prevents shell injection in
 situations where these were directly exposed to adversarial
 input, which would have been a terrible idea to begin with.
 Reported by rabbit.

Changes since OpenSSH 10.2
==========================

This release contains some relatively minor security fixes as well
as a number of feature improvements and general bugfixes.

Security
========

 * ssh(1): validation of shell metacharacters in user names supplied
 on the command-line was performed too late to prevent some
 situations where they could be expanded from %-tokens in
 ssh_config. For certain configurations, such as those that use a
 "%u" token in a "Match exec" block, an attacker who can control
 the user name passed to ssh(1) could potentially execute arbitrary
 shell commands. Reported by Florian Kohnhäuser.

 We continue to recommend against directly exposing ssh(1) and
 other tools' command-lines to untrusted input. Mitigations such
 as this can not be absolute given the variety of shells and user
 configurations in use.

 * sshd(8): when matching an authorized_keys principals="" option
 against a list of principals in a certificate, an incorrect
 algorithm was used that could allow inappropriate matching in
 cases where a principal name in the certificate contains a
 comma character. Exploitation of the condition requires an
 authorized_keys principals="" option that lists more than one
 principal *and* a CA that will issue a certificate that encodes
 more than one of these principal names separated by a comma
 (typical CAs strongly constrain which principal names they will
 place in a certificate). This condition only applies to user-
 trusted CA keys in authorized_keys, the main certificate
 authentication path (TrustedUserCAKeys/AuthorizedPrincipalsFile)
 is not affected. Reported by Vladimir Tokarev.

 * scp(1): when downloading files as root in legacy (-O) mode and
 without the -p (preserve modes) flag set, scp did not clear
 setuid/setgid bits from downloaded files as one might typically
 expect. This bug dates back to the original Berkeley rcp program.
 Reported by Christos Papakonstantinou of Cantina and Spearbit.

 * sshd(8): fix incomplete application of PubkeyAcceptedAlgorithms
 and HostbasedAcceptedAlgorithms with regard to ECDSA keys.
 Previously if one of these directives contains any ECDSA algorithm
 name (say "ecdsa-sha2-nistp384"), then any other ECDSA algorithm
 would be accepted in its place regardless of whether it was
 listed or not. Reported by Christos Papakonstantinou of Cantina
 and Spearbit.

 * ssh(1): connection multiplexing confirmation (requested using
 "ControlMaster ask/autoask") was not being tested for proxy mode
 multiplexing sessions (i.e. "ssh -O proxy ..."). Reported by
 Michalis Vasileiadis.

New features
------------

 * ssh(1), sshd(8): support IANA-assigned codepoints for SSH agent
 forwarding, as per draft-ietf-sshm-ssh-agent. Support for the new
 names is advertised via the EXT_INFO message. If a server offers
 support for the new names, then they are used preferentially.

 Support for the pre-standardisation "@openssh.com" extensions for
 agent forwarding remains supported.

 * ssh-agent(1): implement support for draft-ietf-sshm-ssh-agent
 "query" extension.

 * ssh-add(1): support querying the protocol extensions via the
 agent "query" extension with a new -Q flag.

 * ssh(1): support multiple files in a ssh_config RevokedHostKeys
 directive. bz3918

 * sshd(8): support multiple files in a sshd_config RevokedKeys
 directive bz3918

 * ssh(1): add a ~I escape option that shows information about the
 current SSH connection.

 * ssh(1): add an "ssh -Oconninfo user@host" multiplexing command
 that shows connection information, similar to the ~I escapechar.

 * ssh(1): add an "ssh -O channels user@host" multiplexing command to
 get a running mux process to show information about what channels
 are currently open.

 * sshd(8): add 'invaliduser' penalty to PerSourcePenalties, which is
 applied to login attempts for usernames that do not match real
 accounts. Defaults to 5s to match 'authfail' but allows
 administrators to block such attempts for longer if desired.

 * sshd(8): add a GSSAPIDelegateCredentials option for the server, 
 controlling whether it accepts delegated credentials offered by
 the client. This option mirrors the same option in ssh_config.
 GHPR614

 * ssh(1), sshd(8): support the VA DSCP codepoint in the IPQoS
 directive.

 * sshd(8): convert PerSourcePenalties to using floating point time, 
 allowing penalties to be less than a second. This is useful if you
 need to penalise things you expect to occur at >=1 QPS.

 * ssh-keygen(1): support writing ED25519 keys in PKCS8 format.
 GHPR570

 * Support the ed25519 signature scheme via libcrypto.

Bugfixes
--------

 * sshd(8): make IPQoS first-match-wins in sshd_config, like other
 configuration directives. bz3924

 * sshd(8): fix potential crash when MaxStartups is using a single
 argument (i.e. not using the MaxStartps x:y:z form) to a value
 below 10. bz3941

 * sshd(8): fix a potential hang during key exchange if needed DH
 group values were missing from /etc/moduli.

 * ssh-agent(1): fix return values from extensions to be correct wrt
 draft-ietf-sshm-ssh-agent: extension requests should indicate
 failure using SSH_AGENT_EXTENSION_FAILURE rather than the generic
 SSH_AGENT_FAILURE error code. This allows the client to discern
 between "the request failed" and "the agent doesn't support this
 extension".

 * ssh(1): use fmprintf for showing challenge-response name and info
 to preserve UTF-8 characters where appropriate. Prompted by GitHub
 PR#452.

 * scp(1): when uploading a directory using sftp/sftp (e.g. during a
 recursive transfer), don't clobber the remote directory
 permissions unless either we created the directory during the
 transfer or the -p flag was set. bz3925

 * All: implement missing pieces of FIDO/webauthn signature support, 
 mostly related to certificate handling and enable acceptance of this
 signature format by default. bz3748 GHPR624 GHPR625

 * sshd_config(5): make it clear that DenyUsers/DenyGroups overrides
 AllowUsers/AllowGroups. Previously we specified the order in which
 the directives are processed but it was ambiguous as to what
 happened if both matched.

 * ssh(1): don't try to match certificates held in an agent to
 private keys. This matching is done to support certificates that
 were loaded without their private key material, but is
 unnecessary for agent-hosted certificate which always have
 private key material available in the agent. Worse, this matching
 would mess up the request sent to the agent in such a way as to
 break usage of these keys when the key usage was restricted in
 the agent. bz3752

 * sftp(1): if editline has been switched to vi mode (i.e. via "bind
 -v" in .editrc), setup a keybinding so that command mode can be
 entered.

 * ssh(1), sshd(8): improve performance of keying the sntrup761 key
 agreement algorithm.

 * ssh(1), sshd(8): enforce maximum packet/block limit during
 pre-authentication phase.

 * sftp(1): don't misuse the sftp limits extension's open-handles
 field. This value is supposed to be the number of handles a
 server will allow to be opened and not a number of outstanding
 read/write requests that can be sent during an upload/download.

 * sshd(8): don't crash at connection time if the main sshd_config
 lacks any subsystem directive but one is defined in a Match block.
 bz3906

 * sshd_config(5): add a warning next to the ForceCommand directive
 that forcing a command doesn't automatically disable forwarding.

 * sshd_config(5): add a warning that TOKENS are replaced without
 filtering or escaping and that it's the administrator's
 responsibility to ensure they are used safely in context.

 * scp(1): correctly quote filenames in verbose output for local->
 local copies. bz3900

 * sshd(8): don't mess up the PerSourceNetBlockSize IPv6 mask if
 sscanf didn't decode it. GHPR598

 * ssh-add(1): when loading FIDO2 resident keys, set the comment to
 the FIDO application string. This matches the behaviour of
 ssh-keygen -K. GHPR608

 * sshd(8): don't strnvis() log messages that are going to be logged
 by sshd-auth via its parent sshd-session process, as the parent
 will also run them though strnvis(). Prevents double-escaping of
 non-printing characters in some log messages. bz3896

 * ssh-agent(1): escape SSH_AUTH_SOCK paths that are sent to the
 shell as setenv commands. Unbreaks ssh-agent for home directory
 paths that contain whitespace. bz3884

 * All: Remove unnecessary checks for ECDSA public key validity.

 * sshd(8): activate UnusedConnectionTimeout only after the last
 channel has closed. Previously UnusedConnectionTimeout could fire
 early after a ChannelTimeout. This was not a problem for the
 OpenSSH client because it terminates once all channels have
 closed but could cause problems for other clients (e.g. API
 clients) that do things differently. bz3827

 * All: fix PKCS#11 key PIN entry problems introduced in
 openssh-10.1/10.2. bz3879

 * scp(1): when using the SFTP protocol for transfers, fix implicit
 destination path selection when source path ends with "..". bz3871

 * sftp(1): when tab-completing a filename, ensure that the completed
 string does not end up mid-way through a multibyte character, as
 this will cause a fatal() later on. GHPR#587

 * ssh-keygen(1): fix crash at exit (visible via ssh-keygen -D) when
 multiple keys loaded.

 * scp(1)/sftp(1): correctly display bandwidths >2GBps in the
 progress meter.

Portability
-----------

 * sshd(8): fix condition introduced in openssh 10.2p1 stable branch
 here a PAM module that changed the username between
 SSH_MSG_USERAUTH_REQUEST messages during authentication could
 confuse the PAM stack and let it proceed with a different
 understanding of the active username than the rest of sshd.
 Reported by Mike Damm.

 * sshd(8): immediately report interactive instructions to clients
 when using keyboard-interactive authentication with PAM. bz2876

 * sshd(8): fix duplicate PAM messages under some situations.

 * sshd(8): don't leak PAM handle on repeat invocations. bz3882

 * All: support linking libcrypto implementations (e.g. BoringSSL)
 that require libstdc++.

 * sshd(8): fix ut_type for btmp records, correctly using
 LOGIN_PROCESS and USER_PROCESS.

 * sshd(8): allow uname(3) in the seccomp sandbox. This is needed by
 zlib-ng on RISC-V platforms.

 * All: Remove remaining OpenSSL_add_all_algorithms() calls.
 We already have OPENSSL_init_crypto() in the compat layer.
 Prompted by github PR#606

 * All: fix builds on older Mac OS wrt nfds_t.

 * mdoc2man: several improvements including better support for Dl
 and Ns inside Ic.

Checksums:
==========

 - SHA1 (openssh-10.3.tar.gz) = 854863c04cd28242d73ac6c3ee9c37fa756f1a2f
 - SHA256 (openssh-10.3.tar.gz) = aCU5P47rM+m4N8/i2JOHMOMhafMYqBhvQQSnPXczN5M=

 - SHA1 (openssh-10.3p1.tar.gz) = 9c78838ec07af14aff54f3755ac56ce6812452a9
 - SHA256 (openssh-10.3p1.tar.gz) = VmgqNruS3PS08Bb9jsjnQFm3mo3iXBXWcNcx59GORfQ=

Please note that the SHA256 signatures are base64 encoded and not
hexadecimal (which is the default for most checksum tools). The PGP
key used to sign the releases is available from the mirror sites:
https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/RELEASE_KEY.asc

Reporting Bugs:
===============

- Please read https://www.openssh.com/report.html
 Security bugs should be reported directly to openssh@openssh.com

OpenSSH 10.2/ 10.2p1 (2025-10-10)

OpenSSH 10.2 was released on 2025-10-10. It is available from the
mirrors listed at https://www.openssh.com/.
OpenSSH is a 100% complete SSH protocol 2.0 implementation and
includes sftp client and server support.

Once again, we would like to thank the OpenSSH community for their
continued support of the project, especially those who contributed
code or patches, reported bugs, tested snapshots or donated to the
project. More information on donations may be found at:
https://www.openssh.com/donations.html

Future deprecation warning
--------------------------

 * A future release of OpenSSH will deprecate support for SHA1 SSHFP
 records due to weaknesses in the SHA1 hash function. SHA1 SSHFP
 DNS records will be ignored and ssh-keygen -r will generate only
 SHA256 SSHFP records.

 The SHA256 hash algorithm, which has no known weaknesses, has
 been supported for SSHFP records since OpenSSH 6.1, released in
 2012.

Changes since OpenSSH 10.1
==========================

This is a bugfix release, primarily to fix a problem that rendered
ssh(1) unusable when ControlPersist was enabled.

Bugfixes
--------

 * ssh(1): fix mishandling of terminal connections when
 ControlPersist was active that rendered the session unusable.
 bz3872

 * ssh-keygen(1): fix download of keys from PKCS#11 tokens.

 * ssh-keygen(1): fix CA signing operations when the CA key is held
 in a ssh-agent(1). bz3877

Portability
-----------

 * All: support platforms without mmap(2), e.g. WASM builds such as
 https://hterm.org

 * All: fix builds on FreeBSD for missing fnctl.h include.

 * All: fix builds on MacOS =3 version check.

 * sshd(8), ssh(1): Use SSH_TUN_COMPAT_AF on FreeBSD. Otherwise tun
 forwarding from other OSes fails as soon as the first IPv6 message
 is sent by the other side (which is usually a Router Solicitation
 ICMPv6 message which is sent as soon as the interface is up).

 * ssh(1), ssh-agent(8): check for nlist function presence before
 attempting to use it instead of relying on the presence of the
 nlist.h header. Mac OS X, for example, has the header but not
 the function in the 64bit libraries.

 * All: fill in missing system header files.

 Create replacement header files inside openbsd-compat for common
 he

PAN's pipeline reviewed approximately 1 open sources for this article. No human editor reviewed this article before publication.

Related Reads

Show on timeline →