OpenSSH 10.6p2, released 5 November 2026, closes a password authentication bypass on Linux that uses musl with PAM turned off. Alpine is the common case. Anyone who can reach sshd can log in as an account whose shadow field is *, the mark for an account that should never take a password. The password can be any string from 257 to 1024 bytes. One connection is enough.
No CVE had been assigned when 10.6p2 shipped. Damien Miller told operators of these systems to set PasswordAuthentication to no, or to disable SSH, immediately. Özgün Kültekin of Wakefield reported the bug. The write-up is at sshhole.com.
Hadrian is scanning customer environments through Atlas for this, looking for internet-facing sshd on musl that still accepts password logins.
Technical overview
Where this shows up from the outside
The bug matters where sshd answers on a reachable address. A cloud VM, a jump host left open on port 22, an appliance image built on Alpine, a router or embedded board on OpenWrt or Yocto. A container that never runs sshd is unaffected. That covers most Alpine application images.
The login needs two accounts. One whose password field is *. Another with a real $5$ or $6$ hash, so sshd has a salt to borrow. One real password on the machine makes every * account reachable.
Official Alpine tiny-cloud images, the qcow2, VHD, and AMI builds from 3.18.11 through 3.24.3, ship an alpine user with * in the shadow field and passwordless doas. They are safe on first boot. They become exploitable as soon as anyone sets a console password or user-data adds a user with hashed_passwd. The attacker gets a shell as alpine, then root.
Images brought up through cloud-init already have PasswordAuthentication no. This bug does not apply to them.
Root has been root:* on Alpine since 3.16. OpenSSH's default PermitRootLogin prohibit-password still blocks password login as root. The alpine user, a key-only deploy user created with adduser and no password, and directory users with no shadow entry are still reachable. Those directory users come in through nslcd, winbind, or sssd via musl-nscd. If that user can become root, the attacker is root.
How the check fails
Without PAM, sshd calls crypt() and compares the result with the field in /etc/shadow. A real hash looks like $6$salt$.... A * has no salt.
Since the fix for CVE-2016-6210, sshd still calls crypt() for those accounts, using another account's salt, so a missing user and a real user take about the same time to reject. musl's SHA-256 and SHA-512 crypt() refuse a key longer than 256 bytes and return the string * to mean the call failed. The stored field is * too. The comparison succeeds.
Here is what that looks like on an affected Alpine 3.22 host. The password is 300 A's.
$ ssh alpine@alpine-box
alpine@alpine-box's password:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Welcome to Alpine Linux 3.22
Kernel 6.12.0-0-lts on an x86_64 (/dev/ttyS0)
alpine:~$ doas -s
# grep ^alpine: /etc/shadow
alpine:*:20324:0:99999:7:::
#musl started returning * on crypt() failure in 2012, and capped those hashes at 256 bytes the same month. OpenSSH started borrowing a salt in 2016. Alpine switched locked root from ! to * in 3.16, in 2022, because ! without PAM also disables SSH keys. Each change is correct on its own. Together, a locked account accepts a password.
Kültekin found it by building sshd against glibc and musl, with and without PAM, and sending about 17,600 bad logins. Every build rejected them except musl without PAM.
What to do
Upgrade, then restart the daemon.
Fixed openssh packages:
Point releases 3.21.10, 3.22.8, 3.23.8, and 3.24.4 carry them. 3.16 through 3.20 are out of regular support and still received the backport. New cloud images from those point releases onward ship the fix. Older images need it on every running instance.
If you cannot upgrade yet, confirm key login from a second session and keep the current one open. Then turn password authentication off.
mkdir -p /etc/ssh/sshd_config.decho 'PasswordAuthentication no' > /etc/ssh/sshd_config.d/00-no-passwords.confrc-service sshd restartsshd -T | grep -i passwordauthentication
That drop-in directory is read from Alpine 3.19 onward. On 3.16 through 3.18, set PasswordAuthentication no in /etc/ssh/sshd_config itself. The last command should print passwordauthentication no.
Then do the same for every reachable sshd on musl. A patched base image does not update the VM that has been up since spring.
How to tell if someone already got in
In /var/log/messages, look for Accepted password for an account that has no password. That is alpine, root, or any key-only user. Cross-check /etc/shadow. A * in that field means the account cannot accept a password. An Accepted password line for it means this bug was used, or a password was set and later cleared.
Also review doas use, new users, new authorized_keys, and files changed on hosts that were reachable from the internet. If you cannot rule the login out, rebuild the machine from a fixed image. Cleaning a host that already handed out a shell leaves the next login in place.




