Safeguard
Vulnerability Analysis•

OpenSSH 10.6 Security Fixes: Which Ones Your Config Can Actually Reach

OpenSSH 10.6 shipped on 6 Oct with fixes for sftp path handling, compression side channels, GSSAPI state and more. Most depend on options you can check in a minute.

Safeguard Security Team
6 min read

OpenSSH 10.6 was released on 6 October 2026 with what the release notes call "a number of security fixes". None of them carries a CVE in the notes. The project also said it has received a large number of security reports recently, many found by AI models or with AI assistance, and that it will make more frequent releases instead of batching fixes for the next planned one.

That second point is worth noticing. The team wrote that bugs found by AI tools are often found again independently by other researchers, which "suggests that adversaries who do not report bugs to OSS projects are likely to be able to discover these bugs too." Expect more OpenSSH releases than you're used to, and plan to take them faster.

What's affected

All fixes are in OpenSSH 10.6 (portable 10.6p1). Here are the security items from the release notes, grouped by what has to be true for each to matter.

Client side, needs an untrusted server or untrusted input:

  • sftp recursive copy. sftp now validates paths returned by the server more strictly, to stop a malicious server manipulating a recursive copy into writing outside its target directory. Reachable when you pull directories with sftp from a server you don't fully trust.
  • Usernames with $ or \. ssh now refuses these characters in usernames given on the command line, because a username from an untrusted source could inject into a shell context through ProxyCommand, Match exec and similar. Usernames set with User in config files aren't restricted. The notes still recommend against passing untrusted input to the ssh command line at all.

Both sides, needs compression:

  • Compression side channel. ssh and sshd disable the LZ77 dictionary coder to mitigate an attack described in "Crossing the Streams: SSH Plaintext Recovery via a Common Compression Context in Multiplexed Channels" by Fabian Bäumer and Marcus Brinkmann. An attacker who controls input on one channel can learn secrets from another channel through ciphertext lengths, because all channels share one compression dictionary. This only matters if compression is on and trusted and untrusted traffic share a connection. Compression will now be less effective.
  • Inflation limit. Compressed payloads can no longer inflate past the maximum packet length.

Server side, needs a specific option:

  • GSSAPI state. sshd now stores GSSAPI credentials only after successful authentication and resets GSSAPI state between attempts. Matters only with GSSAPIAuthentication yes, common in Kerberos environments.
  • restrict and tunnels. The restrict keyword in authorized_keys was not applied to tunnel forwarding. Matters only if PermitTunnel is enabled, which is off by default. The notes say this is separate from a related fix in 10.5.
  • Options set to none in Match blocks. Options documented as accepting none, including AuthorizedPrincipalsFile, were read as a literal file name when overridden in a Match block.
  • Platforms without file descriptor passing. On systems such as QNX 6, SCO OpenServer 5, or builds configured with --disable-fd-passing, the post-authentication process kept root privilege. 10.6 disables GatewayPorts and StreamLocalForwarding there.

Other: ssh-keygen fixed a Daylight Saving Time bug that could create certificates with expiry times off by up to an hour.

How to check if you're exposed

Check versions. Distribution packages often backport fixes without changing the upstream version number, so also read your vendor's advisory:

ssh -V
dpkg -l openssh-server openssh-client 2>/dev/null | grep ^ii
rpm -q openssh-server openssh-clients 2>/dev/null

Then check the options that gate the server fixes. sshd -T prints the effective configuration:

sudo sshd -T | grep -iE "^(compression|gssapiauthentication|permittunnel|authorizedprincipalsfile) "

And on clients, check what a given host connection will use:

ssh -G bastion.example.com | grep -iE "^(compression|proxycommand) "

Finally, look for automation that builds ssh command lines from data: deploy scripts that take a username from an inventory file, CI jobs that read a host and user from a pull request, or tools that wrap ssh with user input.

grep -rnE 'ssh .*\$\{?[A-Za-z_]*[Uu][Ss][Ee][Rr]' scripts/ .github/ 2>/dev/null

What to do now

  1. Install 10.6 or your vendor's patched package on bastions, CI runners and any host that runs sftp against outside servers first. Those are the most reachable cases.
  2. Turn compression off unless you have a measured need. Set Compression no in ssh_config and sshd_config. If you need compression, do it at the application level, which the release notes say is both more effective and immune to this class of attack.
  3. Keep PermitTunnel no unless you use tunnel forwarding. If you do, re-test restrict keys after upgrading.
  4. Stop passing untrusted usernames on the ssh command line. Map them to User entries in a generated config file instead.
  5. Rebuild container images that ship OpenSSH once your base distribution publishes a patched package. An image keeps whatever client it was built with.

Why it matters

The release notes describe a shift: many more reports, more of them machine-found, and a promise of faster releases. For defenders, that means the gap between a fix landing upstream and attackers knowing about the bug is shrinking. Treating OpenSSH as a slow-moving, upgrade-once-a-year package no longer fits.

Most of these fixes still need a specific option or a specific use to be reachable. That is useful: a short config audit tells you which hosts to patch today and which can wait for the normal cycle.

Try it yourself

Pick five hosts: a bastion, a CI runner, a database server, a developer laptop and a container image. Run sshd -T or ssh -G on each and record compression, GSSAPI and tunnel settings. Mark which 10.6 fixes each host can actually reach.

Click through it at your own pace, or open it full screen.

Quick check

A server runs with the default PermitTunnel setting. Does the restrict keyword fix change anything for it?

Not in practice. The bug was that restrict didn't apply to tunnel forwarding, and PermitTunnel is disabled by default.

Why did OpenSSH change compression instead of just warning users?

Because channels in one SSH session share a compression dictionary, attacker input on one channel can leak secrets from another through ciphertext length. Disabling the LZ77 dictionary coder removes that shared state.

Are usernames set with the User directive in ssh_config affected by the new character check?

No. The release notes say only usernames entered on the command line are checked for $ and \.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.