OpenSSH 10.4: Patch the Clients First, Then Try Post-Quantum Keys
OpenSSH 10.4 fixes sftp and scp bugs a malicious server could exploit, tightens re-keying, and adds experimental ML-DSA 44 + Ed25519 signatures. Patch the clients first.
Umut Korkmaz
Published: 4 min read
On this page6
OpenSSH 10.4 was released today, and the first two items in its security section are about the clients, not sshd. A malicious server could make sftp or scp write files somewhere you didn't intend. In many teams, scp and sftp run far more often from deploy scripts, CI artifact pulls and backup jobs than from a person at a terminal, so that's where this release matters. It also adds experimental, opt-in support for post-quantum SSH signatures.
Patch the clients first
The two fixes, as the announcement describes them:
sftp host:/path .: when downloading on the command line, a malicious server could make the file land in an unexpected location.scpbetween two remote destinations: a malicious server could write files to the parent directory of the intended target directory.
The Swival Security Scanner identified both. The same release also fixes a possible client-side use-after-free if the server changes its host key during a key re-exchange.
The trust direction is what matters. SSH hardening usually means protecting servers from clients. In these bugs the client is the exposed side, because it trusts what the server sends back. So you need to patch the machines that connect out: CI runners, build agents, backup hosts, jump boxes and laptops. Upgrading sshd across your fleet doesn't fix any of those. The riskiest ones talk to servers you don't fully control, like a partner's SFTP drop or a host that might already be compromised.
The announcement lists no CVE identifiers. If your tooling works from CVE feeds, don't count on it to flag old clients. Run ssh -V inside your runner and deploy images yourself.
Server-side items worth a config grep
- internal-sftp truncation. With
internal-sftp, which isn't the default, sshd silently truncated long command lines after the 9th argument. A security-relevant option in the 10th or later position was discarded. If you have a longinternal-sftpline inSubsystemorForceCommand, count its flags and check the ones you rely on. DisableForwarding=yesdidn't overridePermitTunnel=yes, even though the docs say it does.PermitTunnelis off by default.- GSSAPI pre-auth DoS, only when
GSSAPIAuthenticationis enabled, which is also off by default.MaxAuthTriesdidn't mitigate it, butPerSourcePenaltieswould penalise it. There's also a new documentation note thatGSSAPIStrictAcceptorCheckis ineffective when the server is joined to Windows Active Directory. - Minimum authentication delay. In a number of cases it wasn't being enforced.
Three changes that can break things
- Stricter re-keying. ssh and sshd now disconnect a peer that sends non-KEX messages during a post-authentication key re-exchange. Before, a malicious peer could keep sending them without penalty, and they were buffered and wasted memory. Implementations that don't restrict messages during key exchange, as RFC 4253 section 7.1 requires, may now be disconnected. Test long tunnels and big transfers against any peer that isn't OpenSSH: appliances, embedded stacks, in-house clients.
- seccomp failures are fatal on Linux. With the seccomp sandbox enabled, sshd now stops if it can't enable SECCOMP or NO_NEW_PRIVS. It used to log the error and keep running. Systems without them should disable the sandbox at configure time.
sshd -Gprints mixed-case names, such asPubkeyAuthentication, instead of lowercase only. Compliance scripts that grep for lowercase names will quietly stop matching.
The fix for the last one is one flag:
sshd -G | grep -i '^passwordauthentication'
Post-quantum signatures, off by default
The new feature is experimental support for a composite post-quantum signature scheme that combines ML-DSA 44 and Ed25519, specified in draft-miller-sshm-mldsa44-ed25519-composite-sigs. That's an individual Internet-Draft, not a finished standard. The draft's stated goal is security against both quantum and classical adversaries: you add a lattice-based signature and keep Ed25519, and a forger has to break both.
To use it, you add it to HostKeyAlgorithms, PubkeyAcceptedAlgorithms and related options, and generate keys with ssh-keygen -t mldsa44-ed25519. The algorithm name in the draft is [email protected].
Opt-in is the right default. The scheme is labeled experimental, the spec is still a draft, and both ends of a connection have to support it. It isn't ready for production host keys, but it's worth learning in a lab:
ssh -V # confirm the build is 10.4
ssh -Q key # key types this build reports
ssh-keygen -t mldsa44-ed25519 -f ~/.ssh/id_pq_lab
This release also replaces the wildcard pattern matcher with an NFA-based one, which avoids the old matcher's exponential worst case.
What I'm doing about it
Here's the order I'd give a team this week:
- List every place scp or sftp runs unattended, and update those clients as soon as your distro ships the fix.
- Grep sshd configs for
internal-sftp,PermitTunnelandGSSAPIAuthentication. - Make every
sshd -Gcheck case-insensitive. - Run a long tunnel and a large transfer against each non-OpenSSH peer.
- Try an
mldsa44-ed25519key between two throwaway VMs, and go no further than that.
On my side, the VPS where I self-host Next.js and the machines that connect to it come first. The post-quantum keys stay in the lab. I'm working through CEH material right now, and this release is a good reminder that the client isn't automatically the safe side.
Sources
Primary references used for this post.