Setting a password for one user on an Alpine Linux server can quietly open SSH logins for every account on it whose password field is a bare asterisk. That is the practical shape of CVE-2026-123158, a password authentication bypass in OpenSSH's server daemon, sshd, fixed in Portable OpenSSH 10.6p2 on November 5, 2026. Alpine shipped patched packages for its branches the same day. If your Alpine hosts run sshd with password logins enabled, upgrade and restart it today.
The CVE record rates the flaw 8.1 (High) and limits it to Linux builds that use the musl C library without PAM (Pluggable Authentication Modules, the login framework most distributions send passwords through). Alpine is the best-known platform built that way: its standard openssh-server package ships without PAM. Debian, Ubuntu, Fedora and other glibc-based systems are not affected, and neither is any sshd that checks passwords through PAM, according to Cycode's analysis. Researchers have nicknamed it "*sshole".
Exploitation status matters for triage here. CISA's enrichment of the CVE record marks exploitation as proof of concept, and the record links public lab and reproduction repositories. Orca Security reported on November 5 that no exploitation in the wild had been seen. The CVE is not in CISA's Known Exploited Vulnerabilities catalog. With reproduction steps public and the bug reachable over the network with no credentials, that window should be treated as short.
Why a long password matches an account with no password
Without PAM, sshd verifies passwords itself by calling the C library's crypt() function and comparing the result with the stored value in /etc/shadow. Per Alpine's advisory, when an account's stored field is too short to contain a salt, sshd borrows the salt from another local account. musl's SHA-256 and SHA-512 password hashing refuses keys longer than 256 bytes and signals that failure by returning a single * rather than an error value. A single * is also what Alpine stores for accounts that have no usable password. The two strings match, and the login succeeds. The CVE record puts the working range at passwords between 256 and 1,024 characters.
The OpenSSH maintainers say in the 10.6p2 release notes that they consider the root cause to sit outside sshd, but that it is exploitable through sshd and can be avoided there. The fix does exactly that: sshd now refuses a match when the stored hash is shorter than four characters, which rules out the lone asterisk.
The salt-borrowing step explains the precondition most coverage lists without comment. Alpine says a host is only exploitable if at least one local account holds a real SHA-256 ($5$) or SHA-512 ($6$) hash. A box where nobody has ever set a password has nothing to borrow. So the event that arms the bug is mundane: an operator runs passwd once for a break-glass admin, or for console access through a cloud provider's serial port, and every asterisk account on that host becomes reachable over SSH.
Which Alpine accounts are exposed?
Any account whose password field is a single * is exposed when the other conditions hold. Alpine's list covers root on base images from about 3.16 onward, deploy or service users set up for keys and never given a password, users who exist only in a directory service (nslcd, winbind or sssd) without a local shadow line, and the default alpine login baked into its tiny-cloud builds. An account locked with a leading ! stays safe.
Whether root itself falls depends on one directive. Orca's write-up says a default Alpine install yields root from a single connection. Cycode says OpenSSH's default PermitRootLogin prohibit-password keeps root out. Both can be true on different hosts, because plenty of Alpine images and appliances relax that setting. Check yours rather than trusting either default.
The cloud-image case deserves its own line. Alpine says its official tiny-cloud images from 3.18.11 through 3.24.3 create that default alpine login with an asterisk in place of a hash and grant it doas without a password prompt, and that those images turn exploitable once any $6$ hash appears on the machine. For that user, a bypassed login is one command away from root, whatever PermitRootLogin says.
Containers that do not run sshd are out of scope. Containers that do, which is common in CI runners, bastion images and older "SSH into the box" setups, are in scope exactly like a VM. The CVE text could also apply to other Linux builds that pair musl with a PAM-less sshd, a combination found in some embedded and appliance firmware. If you run that kind of device, ask the vendor which OpenSSH build it ships.
Run apk upgrade and restart sshd today
On a supported Alpine branch, the fixed openssh packages are 10.6_p2-r0 on edge, 10.3_p1-r2 on 3.24, 10.2_p1-r1 on 3.23, 10.0_p1-r11 on 3.22 and 9.9_p2-r1 on 3.21. The matching fixed point releases for building new images are 3.24.4, 3.23.8, 3.22.8 and 3.21.10. Alpine also patched the end-of-life 3.16 to 3.20 branches.
| Alpine branch | Fixed openssh package | Fixed point release |
|---|---|---|
| edge | 10.6_p2-r0 | n/a |
| 3.24 | 10.3_p1-r2 | 3.24.4 |
| 3.23 | 10.2_p1-r1 | 3.23.8 |
| 3.22 | 10.0_p1-r11 | 3.22.8 |
| 3.21 | 9.9_p2-r1 | 3.21.10 |
Alpine's procedure is apk upgrade -U -a and then rc-service sshd restart. The second command is not optional: the process already in memory keeps serving logins with the vulnerable code until it is replaced. On a long-lived server, the restart is the step that tends to get skipped.
If you cannot patch a host today, set PasswordAuthentication no in sshd_config, confirm key-based login works from a second session before you reload, and keep your current session open while you test. Builds of openssh-server-pam running with UsePAM yes are not affected. Images built before the fixed point releases keep the bug until you rebuild them, and Cycode says releases older than 3.16 were exploitable in its lab and will get no fixed package, so for those the only real fix is a newer base.
How to check whether an Alpine host was already used
The useful property of this bug for a defender is that no legitimate password login can ever succeed for an asterisk account. Any successful password login for one of those users is evidence, not noise. In ATT&CK terms it is initial access through Valid Accounts (T1078), and it lands in the same authentication log you already collect. The block below checks exposure and then looks for that evidence on a single host, run as root. Alpine's default syslog writes sshd messages to /var/log/messages; adjust the path if you ship logs elsewhere.
sshd -T | grep -iE '^(passwordauthentication|usepam|permitrootlogin) ' awk -F: '$2 == "*" { print $1 }' /etc/shadow awk -F: '$2 ~ /^\$[56]\$/ { print $1 }' /etc/shadow grep 'Accepted password for' /var/log/messages apk info -v openssh-server
Read the output in order. If password authentication is on and PAM is off, and both awk lines print usernames, the host was exposed until you patched. Any Accepted password for line naming a user from the first awk list should be handled as a compromise, which is the same conclusion Orca and Cycode reach. Pull the source address from that line, check what the session did, and rotate keys and secrets reachable from that account, especially where it has doas rights.
Key-only has to live in sshd_config
The lesson outlasts this patch. A lot of us treat an asterisk in /etc/shadow as the way to say "this account logs in with keys only." CVE-2026-123158 shows that the marker is just a string, and on a PAM-less system it shares a value with a library error return. The control that holds is in the daemon: PasswordAuthentication no globally, or in a Match block for the accounts that must never take a password. It is the same point our Velvet Ant analysis made from the other direction: the login path is a stack of small components, and each one's assumptions need checking. Treat that directive as part of your configuration hardening baseline, and audit it across every Alpine host and image you build, not just the ones you patched this week.
For other recent Linux server flaws that turn a narrow condition into remote access, see our coverage of the Linux kernel MPTCP remote root bug and the libssh2 client-side flaw.