
Attackers can log in to accounts that have no password, such as SSH key-only accounts, on some Alpine Linux servers running the standard openssh-server package. They need network access to the server, an account name, and a password between 257 and 1,024 bytes long.
OpenSSH, which rates the flaw critical, released version 10.6p2 today to block it. Alpine has published fixed packages for every release back to 3.16.
The attack works when the OpenSSH server (sshd) checks passwords without the Pluggable Authentication Module (PAM) interface, password logins are enabled, and at least one other account on the machine has a password. Alpine's openssh-server package is built without PAM, and password logins are on by default.
The flaw comes from how sshd works with musl, the C library that Alpine is built on. Non-Linux systems, Linux systems built on glibc, and systems that check passwords through PAM are not affected, said Damien Miller of the OpenSSH project.
He told anyone running an affected system to "set PasswordAuthentication=no or disable SSH for these systems IMMEDIATELY." No attacks using the flaw have been reported.
Who Is Exposed
Alpine's security advisory lists four conditions. A server is exposed when all four are true:
- It runs the
openssh-serverpackage, which is built without PAM, or runsopenssh-server-pamwithUsePAM no. PasswordAuthenticationisyes, which is the OpenSSH default.- An account has
*as its password field, which means no password is set. - At least one other local account has a password hash starting with
$5$or$6$.
The attacker also needs the name of an account with no password. One account with a password is enough to expose every account without one. The attack succeeds on every try with a single connection, according to the advisory.
On Alpine, accounts with no password set include:
- key-only users created with
adduserwithout a password, or withusermod -p '*' - users who come from a directory service through musl-nscd, since they have no shadow entry
root, which has shipped asroot:*in the base image since about Alpine 3.16- the
alpineuser in the official cloud images built with tiny-cloud
Root is protected by the default PermitRootLogin prohibit-password setting and can be reached directly only if PermitRootLogin yes is set. That protection does not help if an exposed account can become root, for example through doas.
The tiny-cloud images from 3.18.11 through 3.24.3 give the alpine user passwordless doas. They are safe at first boot but become open to attack once any $6$ hash exists on the machine, for example after an admin sets a console password. An attacker can then log in as alpine and use doas to become root.
Containers that do not run sshd, systems with PasswordAuthentication no, and cloud images set up through cloud-init, which writes that setting, are not affected. Accounts locked with ! in /etc/shadow are not affected either, and neither are machines where no account has a $-style password hash.
The flaw is not limited to Alpine. Özgün Kültekin of Wakefield, who reported it, names OpenWrt, Buildroot and Yocto in his technical write-up as other musl-based systems to check.
OpenWrt handles SSH with Dropbear by default, as its Dropbear documentation shows, and Kültekin says Dropbear is not affected. On OpenWrt, the flaw can matter only where an admin has installed the OpenSSH server.
How to Fix It
On Alpine, the fix is a package update followed by a restart, because upgrading the package does not restart the running sshd:
- Update the packages:
apk upgrade -U -a - Restart the server:
rc-service sshd restart
Point releases 3.21.10, 3.22.8, 3.23.8 and 3.24.4 already include the fixed package. Branches 3.16 to 3.21 are past their end of support but also got fixed packages.
Cloud instances started from tiny-cloud images older than those point releases still need the update, or the setting below.
If you build OpenSSH yourself, version 10.6p2 includes the change, as its release notes describe.
If you cannot update yet, turning off password logins also stops the attack. First make sure your SSH key login works, and keep your current session open until a new login succeeds. Then set PasswordAuthentication no, check the configuration with sshd -t, and restart sshd.
The advisory gives commands that add the setting in a drop-in file in /etc/ssh/sshd_config.d, which Alpine's default configuration reads from 3.19 onward. They also change every PasswordAuthentication line in /etc/ssh/sshd_config from yes to no, including lines inside a Match block. Afterward, sshd -T | grep -i passwordauthentication should print passwordauthentication no.
The advisory suggests looking in /var/log/messages for sshd lines reading Accepted password for an account that has no password, such as alpine, root or a key-only user. On exposed machines, also review doas use, recently created users, files and authorized keys.
"If you cannot rule out a login, treat the machine as compromised," it says.
Why Long Passwords Work
Without PAM, sshd checks a password itself. It hashes the attempt with crypt(), the C library function that turns a password into its stored form, and compares the result with the stored field.
An account with no password has only * in that field. That is too short to hold a salt, the random prefix of a hash, so sshd borrows the salt of another account that has a real hash.
For the $5$ and $6$ hash types, musl's crypt() refuses passwords longer than 256 bytes and returns * to signal the error. That * matches the stored *, so sshd accepts the login. The upper end of the range is sshd's own limit of 1,024 bytes per password.
This behavior comes from a musl change on August 9, 2012, which made a failed crypt() call return "an unmatchable hash rather than NULL" because many programs did not check for failure. The 256-byte limit followed on August 29, 2012, to protect servers from denial-of-service attacks.
The salt borrowing comes from a July 15, 2016, OpenSSH change that addressed CVE-2016-6210, a flaw that let attackers learn which usernames exist. Kültekin says the problem has existed since then.
The 10.6p2 code change makes sshd refuse a match when the stored field is shorter than four characters. OpenSSH calls it a workaround and says the root cause lies outside sshd. Stable Alpine packages carry a patch for the same problem.
Why the Fix Came the Next Day
Miller's team learned of the flaw earlier this week and shipped the fix as fast as it could. In the release announcement, he said the team now sees long embargoes as dangerous and mainly helpful to attackers, because it has recently seen AI agents find the same bugs again, sometimes within hours.
No CVE identifier had been assigned to the flaw as of today.