OpenSSH CVE-2026-123158 lets long passwords open no-password Alpine accounts; here's how to check and fix your clients' Alpine servers.
On some Alpine Linux servers, an account with no password at all could open for a very long one, and on some cloud images that could mean full control. OpenSSH released 10.6p2 on 5 November 2026 to block the bypass, CVE-2026-123158, nicknamed sshole. Check each client's Alpine servers and embedded Linux appliances today.
* account plus one real-hash account, per Alpine's advisory.Accepted password for on no-password accounts.alpine user has passwordless doas, an admin-rights tool, so a bypass can reach root once a $6$ hash exists.The OpenSSH sshole vulnerability, CVE-2026-123158, is an authentication bypass in the sshd server before 10.6p2 on Linux using musl libc without PAM, the pluggable login framework, per the CVE record. Ethiack reports no exploitation in the wild as of 5 November 2026, and says public reproduction labs exist; CISA has not listed it as of this writing, so recheck the catalog.
NVD lists 8.1 (CVSS 3.1, High). Per Ethiack, musl's hashing function returns * for an oversized password, and sshd can match that against the * stored for a no-password account. Jake Knott of watchTowr told CSO Online: "We'd be extremely surprised if we didn't see SSH brute-forcers attempting this by the weekend."
This Alpine Linux SSH authentication bypass needs all of these, per Alpine's advisory: the openssh-server package, or openssh-server-pam with UsePAM no; PasswordAuthentication yes, OpenSSH's default; one account with * as its password field; and one local account with a $5$ or $6$ hash. Alpine says its official cloud images are safe on first boot, and become exploitable once any $6$ hash exists, such as after an admin sets a console password.
| Product | Branch | Fixed in |
|---|---|---|
| OpenSSH (upstream) | all | 10.6p2 |
Alpine openssh |
edge | 10.6_p2-r0 |
Alpine openssh |
3.24 | 10.3_p1-r2 |
Alpine openssh |
3.23 | 10.2_p1-r1 |
Alpine openssh |
3.22 | 10.0_p1-r11 |
Alpine openssh |
3.21 | 9.9_p2-r1 |
Alpine openssh |
3.20 | 9.7_p1-r6 |
Alpine openssh |
3.19 | 9.6_p1-r3 |
Alpine openssh |
3.18 | 9.3_p2-r4 |
Alpine openssh |
3.17 | 9.1_p1-r7 |
Alpine openssh |
3.16 | 9.0_p1-r6 |
Fixed versions from Alpine's advisory and OpenSSH's release notes. Alpine's fixed packages keep older version numbers, so Ethiack warns version-only scanners flag them falsely.
Check 2 runs from your desk; run the rest as root on the server. The sources we checked date no first exploitation, so search back to when the client first ran an affected build, using the SIEM or syslog archive, because on-device logs usually cover less. A clean on-device result doesn't rule out an earlier login. For an appliance with no shell, use check 2 and open a vendor support case quoting CVE-2026-123158.
Preserve evidence. Copy logs, SSH settings and account files, then hash them before changing anything. Pass: $D.sha256 lists the copied files.
D=/root/ir-sshole-$(date +%F); mkdir -p "$D"
cp -a /var/log/messages* /etc/ssh /etc/passwd /etc/shadow /etc/doas* "$D"/
find "$D" -type f -exec sha256sum {} + | tee "$D.sha256"
Find SSH that offers passwords. This asks each host which login methods it offers, trying no password (PreferredAuthentications). It covers port 22 only, so the asset inventory stays your primary list. Pass: no line contains password.
while read -r H; do printf '%s: ' "$H"
ssh -n -o BatchMode=yes -o ConnectTimeout=5 -o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null -o PreferredAuthentications=none \
probe@"$H" 2>&1 | tail -1
done < client-hosts.txt
Read the package. This confirms musl, lists installed OpenSSH packages and names containers running sshd. Compare with the table, not upstream numbers. Pass: openssh is at or above its branch's row.
ls /lib/ld-musl-*
apk info -v | grep '^openssh'
# Other musl builds: sshd -V 2>&1
for c in $(docker ps -q 2>/dev/null); do docker top "$c" | grep -q sshd && echo "$c runs sshd"; done
Test the conditions. This prints EXPOSED only when password logins, a * account and a real-hash account coexist. Pass: it prints clear.
P=$(sshd -T | grep -ci '^passwordauthentication yes')
S=$(awk -F: '$2=="*"' /etc/shadow | wc -l)
H=$(awk -F: '$2 ~ /^\$[56]\$/' /etc/shadow | wc -l)
[ "$P" -gt 0 ] && [ "$S" -gt 0 ] && [ "$H" -gt 0 ] && echo EXPOSED || echo clear
# openssh-server-pam with UsePAM yes is not affected: sshd -T | grep -i usepam
# Match blocks can change the password setting per user
Search for bypass logins. This lists password logins for accounts without a real hash; any hit means treat the machine as compromised, per Alpine. Pass: no output.
R=$(awk -F: '$2 ~ /^\$[56]\$/{print $1}' /etc/shadow | paste -sd'|' -)
for f in /var/log/messages*; do case "$f" in *.gz) zcat "$f";; *) cat "$f";; esac; done |
grep 'Accepted password for' | grep -Ev "for (${R:-none}) "
# An attacker who set a password on the account drops out of this filter; check 6 covers that
Review footholds. Alpine says to review doas use and recent users, files and authorized keys. Pass: the client recognises the listed accounts, keys, jobs and changed files.
for f in /var/log/messages*; do case "$f" in *.gz) zcat "$f";; *) cat "$f";; esac; done | grep 'doas'
awk -F: '{print $1,$3,$7}' /etc/passwd
find /root /home -name authorized_keys -exec ls -la {} + -exec cat {} +
ls -la /etc/cron* /var/spool/cron/* /etc/periodic/*
find /etc /root /home /usr/local -type f -newer /etc/alpine-release
Work down this list if check 3 fails or check 4 prints EXPOSED.
Preserve evidence. Confirm the hash file from check 1 exists before the upgrade. Pass: the listing shows a non-empty .sha256 file.
ls -l /root/ir-sshole-*.sha256
Upgrade and restart. Alpine says upgrading doesn't restart the running server. Pass: openssh meets its table row and sshd reports started.
apk upgrade -U -a
rc-service sshd restart
apk info -v | grep '^openssh'
rc-service sshd status
# Other musl builds: install OpenSSH 10.6p2 or the vendor's firmware, then restart sshd
Can't patch today? Turn passwords off temporarily. Keep a session open and confirm key login works first, because users without keys lose SSH. Pass: the last command prints passwordauthentication no.
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
# To undo: delete the drop-in and copy /etc/ssh/sshd_config.bak back
Rebuild images. OX Security says Docker and cloud images with the old package must be rebuilt from a fixed base and redeployed. Pass: printed openssh lines meet their table rows.
for c in $(docker ps -q); do docker exec "$c" sh -c "apk info -v | grep '^openssh'"; done
Remove footholds. Delete accounts and keys the client doesn't recognise; if a login can't be ruled out, rebuild the host. Pass: rerun check 6 and only recognised names remain.
deluser --remove-home <unknown-user>
Rotate credentials. On hosts with a check 5 hit, change the passwords of real-hash accounts. Pass: logging in with the old password fails.
passwd <user>
Hardening (agree with the client first). Remove nopass rules, after confirming another admin route, because alpine has no password to answer doas. Pass: this prints nothing.
grep -rn 'nopass' /etc/doas.conf /etc/doas.d
Rerun the checks. Run checks 3 and 5 again. Pass: check 3 shows the fixed row and check 5 prints nothing new.
OpenSSH's release notes credit Özgün Kültekin of Wakefield with the report, and OpenSSH's announcement says the team "learned of the problem yesterday" and considers the root cause outside OpenSSH. The sshhole.com timeline traces it to a 2012 musl change, a 2016 OpenSSH change and a 2022 Alpine change. BleepingComputer reports that AI agents ran about 17,600 authentication tests during the research.
KinoSec's autonomous external network pentest checks whether each client's internet-facing SSH servers answer and offer password login, including Alpine hosts and appliances that fell off the asset list. A version banner can't settle this one, because exposure also depends on libc, PAM settings and account entries, so pair the report with checks 3 to 5 on the hosts it names. Because the pentest runs on demand, you can rerun it after the patch window and hand your client a report showing which SSH services still accept passwords.
The two differ in reach and effort, according to CSO Online. regreSSHion, the 2024 OpenSSH flaw, affected a broader range of systems but required exploit engineering. CVE-2026-123158 is confined to musl systems and needs no such work.
Run these read-only commands as root: sshd -T | grep -i passwordauthentication, then awk -F: '$2=="*"{print $1}' /etc/shadow, then grep 'Accepted password for' /var/log/messages. If a logged password login names an account from the second list, treat the machine as compromised, per Alpine's advisory. A clean on-device result doesn't rule out an earlier login.
* to ! instead of patching?The sshhole.com write-up says not to rely on that, because on musl without PAM ! also disables key-based login, which is why Alpine moved root to *. Upgrade the package, or set PasswordAuthentication no until you can.
Debian, Ubuntu, Fedora and Red Hat Enterprise Linux are not affected, per Ethiack, because they use glibc rather than musl. The sshhole.com write-up names OpenWrt, Buildroot and Yocto as musl-based but gives no version details, and says Dropbear is not affected. Ask the vendors of those clients' routers and appliances whether their firmware runs OpenSSH on musl without PAM, and request a build with OpenSSH 10.6p2.