If you run sshd on a musl-based Linux, you can be logged into without a valid password. Alpine Linux published an advisory on 2026-11-05 for a bug now codenamed SSHhole. Per the advisory, one connection is enough, it works every time, and it needs no retries. OpenSSH 10.6p2 is the upstream fix. No CVE identifier had been assigned at the time of the advisory.
Why a long password beats a missing one
When sshd is built without PAM, it checks a password by hashing the attempt with crypt() and comparing the result to the stored password field. If that stored field is too short to contain a salt, sshd borrows the salt of another account.
musl's crypt() returns the string * as an error indicator when the key is over 256 bytes. An account with no password has exactly * in its stored field. The "hash" matches and the login succeeds.
The attacker needs two things:
- the name of an account whose password field is
*(normal for key-only accounts) - at least one other account on the machine with a
$5$or$6$hash
Then they send a password of 257 to 1024 bytes. One user with a password is enough to make every account without one reachable.
Check whether you are exposed
The advisory says you are affected if all of these hold:
- You run Alpine's
openssh-serverpackage (built without PAM), oropenssh-server-pamwithUsePAM no.openssh-server-pamwithUsePAM yesis not affected. PasswordAuthenticationisyes, which is the OpenSSH default.- An account has
*as its password field. That includesroot(shipped asroot:*since about Alpine 3.16), key-only users made withadduserwithout a password orusermod -p '*', and directory users via musl-nscd. - At least one local account has a
$5$or$6$hash.
Root is protected by the default PermitRootLogin prohibit-password. That does not help if another account that can log in can become root, for example through doas.
Not affected: containers that do not run sshd, systems with PasswordAuthentication no, locked accounts (! in /etc/shadow), and cloud-init images, which write PasswordAuthentication no.
The Risky Bulletin write-up adds that the bug is not universal. It hits musl distros, naming Alpine Linux, OpenWRT, BuildRoot and Yocto. Its author's worry is the long tail of routers and IoT gear that will not get patched soon.
Fixed package versions
| Alpine branch | Fixed openssh |
|---|---|
| edge | 10.6_p2-r0 |
| 3.24 | 10.3_p1-r2 |
| 3.23 | 10.2_p1-r1 |
| 3.22 | 10.0_p1-r11 |
| 3.21 | 9.9_p2-r1 |
| 3.20 | 9.7_p1-r6 |
| 3.19 | 9.6_p1-r3 |
| 3.18 | 9.3_p2-r4 |
| 3.17 | 9.1_p1-r7 |
| 3.16 | 9.0_p1-r6 |
Alpine 3.21.10, 3.22.8, 3.23.8 and 3.24.4 contain the fix. Alpine also patched releases that no longer get regular updates. 3.21 hit end of support on 2026-11-01, and fixed packages go back to 3.16.
The restart is the part people will miss
apk upgrade -U -a
rc-service sshd restart
Upgrading the package does not replace the running daemon. A patched package on disk with an old sshd in memory is still vulnerable. I would check process start time, not package version.
If you cannot patch today
Disabling password authentication closes the hole. Make sure key login works first and keep your current session open until you have tested a new one. The advisory's commands:
mkdir -p /etc/ssh/sshd_config.d
echo 'PasswordAuthentication no' > /etc/ssh/sshd_config.d/00-no-passwords.conf
sed -i.bak -e '1i PasswordAuthentication no' \
-e 's/^\(\s*PasswordAuthentication[^y#]*\)yes/\1no/i' \
/etc/ssh/sshd_config
sshd -t && rc-service sshd restart
sshd -T | grep -i passwordauthentication
The last line should print passwordauthentication no. The drop-in directory is read from Alpine 3.19 onward; older releases ignore it, and the sed covers them. The original is saved as /etc/ssh/sshd_config.bak.
Cloud images are the sneaky case
The official tiny-cloud images (qcow2, VHD, AMI) from 3.18.11 through 3.24.3 ship an alpine user with a * password field and passwordless doas. They are safe on first boot. They become exploitable once any $6$ hash exists, for example when an admin sets a console password or user-data adds a user with hashed_passwd. The attacker gets a shell as alpine and uses doas to reach root.
Images built from 3.21.10, 3.22.8, 3.23.8, 3.24.4 and later include the fix. For anything older, update openssh or disable password auth on every running instance.
Looking for a past compromise
Search /var/log/messages for Accepted password for lines naming an account that has no password: alpine, root, or any key-only user. Also review doas use and recently created users, files and authorized keys. The advisory's guidance: if you cannot rule out a login, treat the machine as compromised.
I would also grep my Dockerfiles and base images. A container without sshd is fine, but a VM image or router firmware built on Alpine, OpenWRT or Yocto may carry exactly this combination.
Sources: