CVE-2026-123158: OpenSSH password authentication bypass on Alpine Linux
CVE-2026-123158 (sshole, CVSS 8.1): OpenSSH password authentication bypass on Alpine and other musl Linux systems without PAM. Affected systems, fixes.
On 5 November 2026, OpenSSH released a fix, 10.6p2, for an sshd vulnerability reported the day before by Özgün Kültekin, a researcher at Wakefield. It is tracked as CVE-2026-123158, and the researcher nicknamed it "sshole".
The flaw allows a password login to an account that has no password. It only affects Linux systems built on the musl C library whose sshd checks passwords without going through PAM.
That is Alpine Linux's default configuration, so Alpine carries most of the risk. Debian, Ubuntu, RHEL and other glibc distributions are not affected.
Alpine published its advisory the same day, with fixed packages for every branch since 3.16. No exploitation had been reported at the time of writing.
Technical summary
Item
Value
Identifier
CVE-2026-123158, published on 5 November 2026 by MITRE
Nickname
"sshole", spelled "*sshole" by the researcher and "SSHhole" in part of the press
Component
sshd, password authentication without PAM (auth-passwd.c, xcrypt.c)
Platforms
Linux with musl: mainly Alpine, but also Buildroot, Yocto or OpenWrt when they ship OpenSSH
Class
CWE-394, unexpected status code or return value
CVSS 3.1
8.1, vector AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H (MITRE, also used by Red Hat). Not yet analyzed by NVD
SSVC (CISA)
Exploitation: poc; automatable: no; technical impact: total
Affected versions
OpenSSH portable before 10.6p2, under the conditions described below
Fix
OpenSSH 10.6p2 (commit 4353fdc, "avoid password authn bypass"); Alpine packages from 3.16 to edge
Discovery
Özgün Kültekin (Wakefield), reported to OpenSSH on 4 November 2026
Exploitation
None observed as of 6 November; not in the KEV catalog
The 8.1 score comes from an attack complexity rated high (AC:H). OpenSSH, for its part, calls the fix "critical" in its release notes.
We read that AC:H as a reflection of configuration preconditions rather than technical difficulty. On a host that meets them, Alpine's advisory describes a deterministic attack that succeeds on the first attempt.
For an affected server, we would therefore treat it as a critical flaw. We discuss this kind of gap between score and actual risk in our article on vulnerability prioritization.
Affected systems
Alpine's advisory sets four conditions, all of which must be met:
sshd checks passwords without PAM. That is the case for Alpine's openssh-server package; the openssh-server-pam variant is only affected with UsePAM no.
Password authentication is enabled (PasswordAuthentication yes, OpenSSH's default).
At least one account has * as its password field. On Alpine, that includes root in base images, accounts created for key-only login, and some directory-backed accounts.
At least one other local account has a real password hash, in $5$ or $6$ format.
Not affected:
glibc distributions (Debian, Ubuntu, RHEL and derivatives, Fedora), as well as macOS and OpenBSD;
any sshd that checks passwords through PAM;
servers configured with PasswordAuthentication no;
accounts locked with ! rather than *;
Dropbear, OpenWrt's default SSH server, and other password login programs, according to musl's maintainer;
Alpine containers that do not run sshd, which is the vast majority.
The root account
In Alpine images, root has had * as its password since 3.16. It remains protected by the default PermitRootLogin prohibit-password, which refuses any password login for root.
A server where that directive has been set to yes, on the other hand, exposes root directly. It is the first setting we would check.
Official cloud images
Alpine's "tiny-cloud" images (qcow2, VHD, AMI), from 3.18.11 to 3.24.3, create an alpine user. Its password field is *, it has passwordless doas, and it has the same name on every instance.
A freshly booted instance is not vulnerable, since no account has a real password. It becomes vulnerable as soon as a $6$ hash appears on the machine:
a password set for console access;
a hashed_passwd passed in user-data;
a service account created by hand.
In our view this is the most serious case, because the missing condition comes from an entirely routine administration task.
Images built from 3.21.10, 3.22.8, 3.23.8 and 3.24.4 include the fix. Instances already running have to be updated one by one. Alpine notes that images using cloud-init write PasswordAuthentication no and are not affected.
Containers and embedded systems
An Alpine container is only exposed if it runs an SSH server with passwords enabled: jump containers, SFTP servers, "SSH in a box" images. It is rare, but it happens.
Updating the package inside the container is not a lasting fix, since the next redeployment brings back the old version. The image has to be rebuilt from a fixed base.
Buildroot or Yocto systems, and OpenWrt routers where OpenSSH has replaced Dropbear, are in the same situation as Alpine if they meet the four conditions. For a device whose firmware you do not control, ask the vendor and disable password authentication if the interface allows it.
How it works
To find the flaw, Özgün Kültekin built sshd in every possible combination: glibc or musl, with or without PAM, with or without a shadow file. He then put each build through about 17,600 unusual login attempts, generated with AI agents.
Only one combination behaved differently from the others: musl without PAM. The defect comes from three choices made separately, over ten years:
In 2012, musl made crypt() return the string * on failure, rather than NULL. Three weeks later, the library added SHA-crypt, with a key limited to 256 bytes; beyond that, crypt() fails.
In 2016, OpenSSH fixed CVE-2016-6210, an account enumeration through response timing. Since then, sshd computes a hash even for an account with no valid one, borrowing the salt of another account on the system. That is where the fourth condition comes from.
In 2022, Alpine 3.16 gave root* instead of !. Without PAM, ! also blocked key-based login, an issue open since CVE-2019-5021.
Without PAM, sshd hashes the password it receives and compares the result, string to string, with the field in /etc/shadow. Under musl, a password longer than 256 bytes makes that computation fail, and it returns *. If the account's field is also *, the comparison succeeds.
Under glibc, crypt() reports the failure differently and sshd already rejects that case. With PAM, crypt() is never called for an account set to *.
The fix adds a guard in sys_auth_passwd(): no match is accepted if the stored hash is shorter than four characters (MIN_PASSWORD_HASH_LEN). No real hash is that short, while the "no password" markers (*, !, x) all are.
The two projects disagree on who is responsible:
OpenSSH writes: "We consider the root cause of this bug to be outside sshd, but it is exploitable via sshd and can be avoided there";
Rich Felker, musl's maintainer, says it is "not a bug in musl just an erroneous use by the caller", while announcing that this behavior "very likely will be changed in the upcoming release cycle".
In practice, the fix to deploy is OpenSSH's. A musl machine whose OpenSSH is not up to date remains exposed, whatever its musl version.
Fixed Alpine packages
Alpine backported the fix to every branch since 3.16, including those no longer maintained (3.16 to 3.20).
Alpine branch
Fixed openssh package (or later)
Point release
edge
10.6_p2-r0
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
3.20
9.7_p1-r6
Package only, branch out of support
3.19
9.6_p1-r3
Package only, branch out of support
3.18
9.3_p2-r4
Package only, branch out of support
3.17
9.1_p1-r7
Package only, branch out of support
3.16
9.0_p1-r6
Package only, branch out of support
Checking a host
Checks are done locally, as root. We advise against testing a login to judge exposure, and against running the unaudited detection scripts circulating since 5 November (OX Security has warned about them).
C library and installed package
cat /etc/alpine-release # Alpine, and which versionldd /usr/sbin/sshd | grep -i musl # is sshd linked against musl?apk info -v 2>/dev/null | grep '^openssh-server'
Then compare the package version with the table above.
an sshd built without PAM shows no usepam line, which is expected;
sshd -T shows the global configuration, while a Match block can re-enable passwords for a user or a network. Read the file, or test a specific case with sshd -T -C user=alpine,host=example,addr=203.0.113.10.
The host was exploitable if both lists are non-empty, passwords are enabled and the package is not fixed.
Beyond root, look first at key-only service and deployment accounts, and at the alpine account on cloud images.
Remediation
In order of effectiveness:
Update, then restart sshd. Alpine's advisory points it out: updating the package does not replace the running daemon.
apk upgrade -U -arc-service sshd restart
Disable password authentication if the update cannot happen right away. First check that key-based login works, and keep a session open while you make the change. Method published by Alpine:
The sshd_config.d directory is only read by default from Alpine 3.19 onward, hence the change to the main file, which also covers Match blocks. The original is kept in sshd_config.bak.
Rebuild images that ship openssh-server (Docker images, VM templates, internal AMIs) from a fixed base. To administer a container, docker exec or kubectl exec avoid running an SSH server in it.
Limit exposure: firewall filtering or VPN access, and removal of the alpine account's passwordless doas where it is not used.
We recommend keeping PasswordAuthentication no once the package is fixed. An SSH server reachable from the Internet rarely needs to accept passwords, and doing without them also rules out brute-force attacks.
One last measure is going around: replacing * with ! in /etc/shadow. It blocks the attack, but without PAM, OpenSSH then treats the account as locked and also refuses key-based login. That is exactly what led Alpine to switch from ! to * in 2022; we reserve it for accounts that are never used to log in.
Looking for compromise
No network indicators have been published. The usable trace is in the authentication logs:
on Alpine, /var/log/messages and its rotated files. An sshd line reading "Accepted password for" that names an account without a password (alpine, root, a key-only account) has no legitimate explanation;
central log collection, the only source left for containers and instances already destroyed.
If such a line shows up, or if the logs do not allow a conclusion on an exposed host, we would treat the machine as compromised:
review of doas usage, recent accounts, modified files and authorized_keys;
rebuilding the machine rather than cleaning it;
rotation of the secrets it held (keys, tokens, passwords to other systems).
Timeline
OpenSSH was notified on 4 November and released the fix the next day, without the lead time distributions are usually given to prepare.
Damien Miller explained the decision on the OpenSSH developers' list. The team has seen "multiple cases of rapid bug rediscovery by AI agents, sometimes within hours", and now considers "long embargo periods to be a dangerous practice that primarily benefits attackers".
The day before, writing about CVE-2026-98432, we described a remote root exploit written by an AI model in under an hour. Both cases point the same way: the time to prepare between a fix and its possible exploitation is shrinking.
Timeline
CVE-2026-123158 timeline
Origins
August 2012
musl changes crypt()
the function returns * on failure; SHA-crypt arrives three weeks later, with a key limited to 256 bytes.
July 2016
Fix for CVE-2016-6210
sshd borrows a real salt for accounts without a valid hash.
May 2022
Alpine 3.16
root moves from ! to * in base images.
Disclosure
4 November 2026
Report to OpenSSH
across about 17,600 unusual logins, only the musl without PAM combination behaves differently.
5 November 2026
OpenSSH 10.6p2 and Alpine advisory
fixed packages for every branch since 3.16, CVE published by MITRE late in the day.
Aftermath
6 November 2026
No exploitation reported
CISA places exploitation at the proof-of-concept stage, and the flaw is not in the KEV catalog.
The first three dates are the technical choices whose combination produces the flaw.
Detection from the outside
Flawfence does not attempt any authentication against your SSH servers, and such a test would add nothing that the local check does not do better. The flaw is in any case poorly suited to remote detection:
the SSH banner gives the OpenSSH version, not the C library or whether PAM is used;
fixed Alpine packages keep their upstream version number, so the banner cannot tell a fixed server from a vulnerable one.
Our role comes earlier. Flawfence lists the SSH servers exposed on the Internet in your name, places their observable versions when possible, and flags those that appear or reappear after a migration.
A password authentication bypass in sshd, OpenSSH's server, nicknamed "sshole". On Linux with musl and without PAM, an account with no password (* in /etc/shadow) can accept a login with a very long password. It is rated 8.1 under CVSS 3.1 and fixed in OpenSSH 10.6p2.
Is my Debian, Ubuntu or RHEL server affected?
No. These distributions use glibc and PAM, and do not meet the conditions. Red Hat confirms that none of its products are affected. The flaw concerns musl systems, Alpine Linux first among them.
Are my Alpine-based Docker containers vulnerable?
Only if they run an SSH server that accepts passwords, which is rare. In that case, rebuild the image from a fixed base rather than updating the container in place.
Which version fixes the flaw?
OpenSSH 10.6p2 upstream. On Alpine, the fixed openssh package depends on the branch: 10.3_p1-r2 on 3.24, 10.2_p1-r1 on 3.23, 10.0_p1-r11 on 3.22, 9.9_p2-r1 on 3.21, and so on down to 3.16. Restart sshd after the update.
How can I protect a server without updating right away?
By disabling password authentication (PasswordAuthentication no), after checking that key-based login works, then restarting sshd. OpenSSH and musl's maintainer both recommend this measure.
Is the flaw being exploited?
No exploitation had been reported as of 6 November 2026, and the flaw is not in CISA's KEV catalog. Reproduction environments are public, however, and CISA places exploitation at the proof-of-concept stage.
How can I tell whether an attacker has logged in?
Search sshd logs for "Accepted password for" lines naming an account that has no password (alpine, root, key-only accounts). Such a line has no legitimate explanation: the machine should be treated as compromised.