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:

  1. You run Alpine's openssh-server package (built without PAM), or openssh-server-pam with UsePAM no. openssh-server-pam with UsePAM yes is not affected.
  2. PasswordAuthentication is yes, which is the OpenSSH default.
  3. An account has * as its password field. That includes root (shipped as root:* since about Alpine 3.16), key-only users made with adduser without a password or usermod -p '*', and directory users via musl-nscd.
  4. 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: