sshhole, also written *sshole, is an OpenSSH flaw tracked as CVE-2026-123158. On Alpine Linux and other musl-based systems where sshd checks passwords without PAM, anyone who can reach the SSH port can log in to an account that has no password, such as a key-only user, by sending any password between 257 and 1,024 bytes long. It takes one connection and needs no guessing. OpenSSH released 10.6p2 on 5 November 2026 and Alpine shipped fixed packages for every release from 3.16 to edge the same day. Public reproduction labs already exist.
Reflects what was publicly known on the last updated date. Every fact links to a primary source at the end of the page.
Only if sshd checks passwords itself on a musl system. That is the default for Alpine's openssh-server package.
You run sshd on Alpine with password logins on
openssh-server, or openssh-server-pam with UsePAM no. PasswordAuthentication defaults to yes
Update openssh and restart sshd today, or turn password logins off now. Steps
You launched an official Alpine tiny-cloud image
AMI, VHD or qcow2 from 3.18.11 through 3.24.3
The alpine user has passwordless doas, so this can be root. Details
You build images or firmware on musl with OpenSSH
Alpine-based appliances, OpenWrt, Buildroot or Yocto builds
Ship OpenSSH 10.6p2 or a backport, and check whether your build uses PAM. Other musl systems
Alpine containers that do not run sshd
Typical application images built FROM alpine
Not affected. Update on your normal schedule.
PAM in use, or PasswordAuthentication no
openssh-server-pam with UsePAM yes; key-only sshd
Not affected. sshd never reaches the vulnerable crypt() comparison.
glibc distributions, BSDs, Dropbear
Debian, Ubuntu, RHEL, Fedora, SUSE, OpenBSD, macOS
Not affected, per OpenSSH and musl.
Accounts locked with ! are not affected. Cloud images provisioned with cloud-init are not affected because cloud-init writes PasswordAuthentication no.
Updating the package is not enough on its own. The running sshd keeps the old code until it restarts.
Check exposure on each Alpine host
passwordauthentication is yes, usepam is no or missing (a build without PAM prints no such line), and both awk commands print names, the host is exploitable.apk info -vv | grep -E '^openssh-server' # which sshd package and version
sshd -T | grep -Ei '^(passwordauthentication|usepam|permitrootlogin)'
awk -F: '$2 == "*" {print "no password: " $1}' /etc/shadow
awk -F: '$2 ~ /^\$[56]\$/ {print "salt donor: " $1}' /etc/shadowUpdate openssh and restart sshd
apk upgrade -U -a
rc-service sshd restart
apk info -v openssh-server # compare with the fixed version for your branchCannot update right now? Turn password logins off
Rebuild images that run sshd
Check logs on hosts that were exposed
Later revisions on the same branch also contain the fix. Upstream, the fix is OpenSSH portable 10.6p2.
| Alpine branch | Fixed openssh | Notes |
|---|---|---|
| edge | 10.6_p2-r0 | OpenSSH 10.6p2 |
| 3.24 | 10.3_p1-r2 | In 3.24.4 |
| 3.23 | 10.2_p1-r1 | In 3.23.8 |
| 3.22 | 10.0_p1-r11 | In 3.22.8 |
| 3.21 | 9.9_p2-r1 | In 3.21.10. Support ended 1 November 2026 |
| 3.20 | 9.7_p1-r6 | Out of support, backported |
| 3.19 | 9.6_p1-r3 | Out of support, backported |
| 3.18 | 9.3_p2-r4 | Out of support, backported |
| 3.17 | 9.1_p1-r7 | Out of support, backported |
| 3.16 | 9.0_p1-r6 | Out of support, backported |
Stable branches carry a backported patch under their existing OpenSSH version, so a 3.24 host showing 10.3_p1 is fixed from -r2. Do not judge exposure by the upstream version number alone.
Disabling password authentication fully mitigates the bug. Confirm key login works first and keep your current session open until a new login succeeds.
These are Alpine's published commands. The drop-in file is read from Alpine 3.19 onward; the sed line covers older releases by flipping every PasswordAuthentication yes in the main config, including inside Match blocks, and saves the original as /etc/ssh/sshd_config.bak.
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 # expect: passwordauthentication noMatch block that sets PasswordAuthentication yes for some users or addresses keeps those logins exposed. Test with sshd -T -C user=NAME,addr=IP,host=HOST.* accounts or locking them with ! also blocks the attack, but without PAM ! disables key logins for that account too.The highest-impact case: a bypass into an account with passwordless root.
Official tiny-cloud images (AMI, Azure VHD and qcow2) 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 because no account has a $6$ hash to borrow a salt from. They become exploitable as soon as one exists, for example after an admin sets a console password or user-data adds a user with hashed_passwd. An attacker then logs in as alpine and runs doas to become root.
Images from 3.21.10, 3.22.8, 3.23.8, 3.24.4 and later include the fixed package. Every instance already running from an older image needs the update or the mitigation, because a patched image does not change a running VM.
Three independently reasonable changes, made years apart, that combine into a login bypass.
Without PAM, sshd checks a password by hashing the attempt with crypt() and comparing the result to the stored password field with strcmp(). A * in that field has never been a valid hash, so traditionally no password could match it.
crypt() returns the string * instead of NULL when it fails, so careless callers see a wrong password rather than crash.*.$5$ or $6$ salt, so rejecting them takes as long as a real check.crypt() return *, which equals the stored *, and sshd accepts the login.Alpine made the condition common in 3.16, when it switched root from ! to * because ! without PAM also blocks key logins. With PAM, the module never runs this comparison, which is why most distributions never saw it.
The OpenSSH fix rejects any stored password field shorter than a minimum hash length before comparing, and copies the shadow entry instead of pointing into libc's static buffer. OpenSSH says it considers the root cause to be outside sshd. musl's Rich Felker says it is "not a bug in musl just an erroneous use by the caller", but expects musl to change the failure behavior in its next release cycle.
Alpine is the common case, not the only one.
The musl advisory covers every OpenSSH before 10.6p2 on musl with UsePAM no and password logins on. The reporter names OpenWrt, Buildroot and Yocto as musl environments to check. Most of these ship Dropbear by default, which is not affected, but images that add OpenSSH without PAM are. If you maintain such a build, move to 10.6p2 or backport the fix commit, and default to PasswordAuthentication no.
A successful attack logs an ordinary password login, to an account that should never accept one.
Search syslog for Accepted password for lines naming alpine, root or any account whose shadow field is *. Any such line is suspicious, because those accounts have no password to accept.
grep 'sshd.*Accepted password for' /var/log/messages*
awk -F: '$2 == "*" {print $1}' /etc/shadow # compare against the names aboveReview doas use, new users, changes to authorized_keys files and recently modified files on exposed machines. Attackers who get in this way will likely add a key so they no longer depend on the bug.
Alpine's advice: if you cannot rule out a login, treat the machine as compromised. Rebuild it on fixed packages and rotate every credential and key it held.
Dates are UTC. OpenSSH learned of the bug one day before release and skipped a long embargo, citing rapid rediscovery of bugs by AI tools. CVE-2026-123158 published the same afternoon. Public proof of concept, no in-the-wild exploitation reported as of 5 November 2026.
2012-08-09
musl changes crypt() to return the string * on failure instead of NULL, so callers that never check for NULL do not crash.
2012-08-29
musl adds SHA-512 crypt with a 256-byte key limit to stop denial of service from huge passwords. Longer keys fail, and so return *.
2016-07-15
To fix the user enumeration timing leak CVE-2016-6210, sshd starts hashing attempts for accounts without a usable hash using another account's salt.
2022-05-23
Alpine 3.16 ships root as root:* instead of root:!, because ! without PAM also blocks SSH key logins.
2026-11-04
Özgün Kültekin of Wakefield reports the bypass to OpenSSH after differential testing of sshd builds against glibc and musl, with and without PAM.
2026-11-05
OpenSSH releases portable 10.6p2. Damien Miller tells operators of musl systems without PAM to set PasswordAuthentication no or disable SSH immediately.
2026-11-05
Alpine publishes its advisory and fixed openssh packages for 3.16 through 3.24 and edge.
2026-11-0515:07 UTC
musl maintainer Rich Felker posts an advisory for OpenSSH and musl users, says Dropbear is not affected, and expects to change the crypt() failure behavior in the next release cycle.
2026-11-0515:46 UTC
MITRE publishes CVE-2026-123158, CVSS 3.1 8.1, linking the fix commit and two public reproduction labs.
2026-11-0517:12 UTC
CISA adds its assessment to the record: proof of concept public, not automatable, total technical impact.
sshhole, also written *sshole or sshole, is the name the reporter gave CVE-2026-123158 on sshhole.com. The * refers to the password field value at the heart of the bug: musl's crypt() returns * when it rejects a password over 256 bytes, which matches the * that marks accounts with no password, so sshd accepts any password from 257 to 1,024 bytes for those accounts.
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 and 3.16 9.0_p1-r6. Point releases 3.21.10, 3.22.8, 3.23.8 and 3.24.4 include them. Restart sshd after upgrading.
CVE-2026-123158, published by MITRE on 5 November 2026 at 15:46 UTC, a few hours after the OpenSSH and Alpine advisories, which say no CVE had been assigned. The record covers OpenSSH before 10.6p2 on Linux with musl libc and no PAM.
The CVE record scores attack complexity high (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H), because the target needs a particular mix of accounts: one with a * password field and another with a $5$ or $6$ hash. OpenSSH and Alpine call it critical. Where those conditions hold, it is one login with no guessing, so patch it as critical.
No. Damien Miller of OpenSSH says the bug does not exist on non-Linux systems, on Linux systems using glibc, or on Linux systems that use PAM for password authentication. glibc's crypt() does not return a bare * on failure.
Only containers that run sshd. Most Alpine application images do not, and are not affected. If your image installs openssh-server and starts sshd with password logins on, rebuild it on the fixed package or set PasswordAuthentication no.
Not with default settings. Alpine ships root with a * password field, but OpenSSH's default PermitRootLogin prohibit-password refuses password logins as root. Root is reachable only with PermitRootLogin yes, or indirectly through another exposed account that can become root, such as the alpine user on tiny-cloud images with passwordless doas.
No. musl maintainer Rich Felker and Alpine's Natanael Copa both say Dropbear and other non-OpenSSH password logins are not affected.
Only with UsePAM yes. If the binary is built with PAM support but the configuration sets UsePAM no, sshd falls back to its own crypt() check and is vulnerable. Damien Miller confirmed this configuration is affected.
No in-the-wild exploitation had been reported as of 5 November 2026, and it is not in CISA's Known Exploited Vulnerabilities catalog. CISA's assessment records a public proof of concept, and the CVE record links two public reproduction labs. The exploit is one long password, so assume scanning will follow quickly.
Vulneron matches new vulnerabilities and public exploits against your live surface, confirms what is actually exploitable for you, and alerts in real time only when it is critical.