Skip to main content
OpenSSH CVE-2026-123158 "SSHole": A Long Password Logs In on Alpine. Patch by Nov 12

OpenSSH CVE-2026-123158 "SSHole": A Long Password Logs In on Alpine. Patch by Nov 12

KU
· Founder & Chief Editor
• 8 min read•2 views

A password-authentication bypass in sshd built without PAM lets a single long password log in to accounts that have no password at all. Alpine is the main target, CISA lists it as exploited, and the federal deadline is November 12. Checks, fixed packages and the one-line stopgap.

Key takeaways

  • CVE-2026-123158, nicknamed SSHole, is a password-authentication bypass in OpenSSH's sshd when it runs without PAM on musl-based Linux, which in practice means Alpine.
  • CISA added it to the KEV catalog on November 9, 2026, with a November 12 deadline.
  • Upgrade to OpenSSH 10.6p2 or your branch's fixed Alpine package and restart sshd, or set PasswordAuthentication no.

Upgrade openssh on every Alpine host, VM image and container that runs sshd, then restart the daemon. CVE-2026-123158 lets one connection with an overlong password log in to accounts that have no password set, such as key-only users. CISA lists it as exploited, and the federal deadline is November 12. If you cannot patch today, turn off password authentication.

Verified against

OpenSSH 10.6p2 and the fixed Alpine packages for 3.16 through 3.24 and edge, against the OpenSSH 10.6p2 release notes, the Alpine Linux security post of November 5, 2026, openssh-portable commit 4353fdc and the CISA KEV catalog feed. Checked November 2026.

What happened, in dates

  • November 5, 2026: OpenSSH 10.6p2 ships with a fix for "password authentication bypass that is exploitable through sshd(8) that affects some Linux systems when built and run with PAM support disabled." The same day, Alpine publishes its advisory and fixed packages for every branch from 3.16 to edge. The bug was reported by Özgün Kültekin of Wakefield.
  • November 9: CISA adds CVE-2026-123158 to the Known Exploited Vulnerabilities catalog. The entry asks for forensic triage, lists ransomware use as unknown, and sets a remediation due date of November 12, 2026.

OpenSSH says it considers the root cause to be outside sshd, but closes the hole there because sshd is where it can be reached.

How a long password becomes a login

Without PAM, sshd checks a password itself. It hashes your attempt with crypt() using the salt from the account's shadow entry, then compares the result with the stored value. Alpine's advisory spells out how that goes wrong on musl:

  1. An account with no password has * in its shadow password field. Stock Alpine ships root:* (the default PermitRootLogin prohibit-password keeps root out), and key-only users, directory-service users without a shadow entry and the alpine user in tiny-cloud images are in the same position.
  2. * is too short to hold a salt, so sshd borrows a salt from another account on the box that has a real $5$ or $6$ hash.
  3. musl's crypt() returns * as its error value when the key is longer than 256 bytes.
  4. A password of 257 to 1,024 bytes therefore "hashes" to *, which matches the stored *, and sshd lets the attacker in.

The upstream commit adds a minimum hash-length check before the comparison, so a stored value as short as * can no longer match. Glibc systems and anything using PAM do not take this path.

Am I affected?

You need all four of these at once: sshd without PAM (the openssh-server package, or openssh-server-pam with UsePAM no), password authentication on (the OpenSSH default), at least one account whose password field is *, and at least one account with a $5$ or $6$ hash.

Bash
# 1. Which sshd build is installed? openssh-server is the non-PAM build.
apk info -v 2>/dev/null | grep '^openssh-server'

# 2. What the running config actually allows (needs root)
sshd -T | grep -E '^(usepam|passwordauthentication) '

# 3. Accounts with no password, and accounts with real hashes
awk -F: '$2 == "*" {print "no-password:", $1}' /etc/shadow
awk -F: '$2 ~ /^\$[56]\$/ {print "hashed:", $1}' /etc/shadow

# 4. Kubernetes: which pods are running an sshd process right now?
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{" "}{.metadata.name}{"\n"}{end}' \
  | while read -r ns pod; do
      kubectl exec -n "$ns" "$pod" -- sh -c 'pgrep -x sshd >/dev/null && cat /etc/alpine-release' 2>/dev/null \
        | sed "s|^|$ns/$pod alpine |"
    done

# 5. An image you build or pull: does it ship the non-PAM sshd?
docker run --rm --entrypoint sh <image> -c 'cat /etc/alpine-release; apk info -e openssh-server'

You are exposed if check 1 shows openssh-server (the non-PAM build prints no usepam line in check 2) or check 2 shows usepam no, check 2 shows passwordauthentication yes, and check 3 prints at least one line of each kind. Check 4 is slow on big clusters, so run it per namespace; it only inspects each pod's default container, and only reports it if that container has a shell, pgrep and Alpine.

Fixed Alpine packages, as of November 11, 2026

Alpine branchFixed openssh packageFixed point release
edge10.6_p2-r0n/a
3.2410.3_p1-r23.24.4
3.2310.2_p1-r13.23.8
3.2210.0_p1-r113.22.8
3.219.9_p2-r13.21.10 (support ended Nov 1)
3.209.7_p1-r6none, unsupported
3.199.6_p1-r3none, unsupported
3.189.3_p2-r4none, unsupported
3.179.1_p1-r7none, unsupported
3.169.0_p1-r6none, unsupported

Upstream, the fix is OpenSSH 10.6p2. Tiny-cloud VM images (qcow2, VHD, AMI) from 3.18.11 through 3.24.3 are safe at first boot but become exploitable once any account gets a $6$ password, and their alpine user has passwordless doas. That makes a hit on that user a root compromise.

What to do now

Patch and restart. Upgrading the package does not replace the daemon that is already running:

Bash
apk upgrade -U -a
rc-service sshd restart
apk info -v openssh-server   # compare with the table above

For containers, rebuild on a fixed base (alpine:3.24.4, 3.23.8, 3.22.8 or 3.21.10) and redeploy. A restart alone pulls nothing new.

Stopgap: turn off password logins. Alpine's default sshd_config reads drop-in files from 3.19 onward; older releases ignore them, and Match blocks in sshd_config need editing separately:

Bash
mkdir -p /etc/ssh/sshd_config.d
echo 'PasswordAuthentication no' > /etc/ssh/sshd_config.d/00-no-passwords.conf
sshd -T | grep '^passwordauthentication '   # expect: passwordauthentication no
sshd -t && rc-service sshd reload

Confirm key-based login works in a second session before you close the one you are in. Our SSH hardening guide covers moving the rest of the fleet to keys and certificates.

Where this breaks

The stopgap does nothing if another config line later turns password authentication back on, so trust the sshd -T output, not the file you edited. Patching does not tell you whether someone already got in. Alpine's advice is to search /var/log/messages for Accepted password for on accounts that have no password, then review doas use, new accounts, new files and authorized_keys. If you cannot rule out a login, treat the machine as compromised and rebuild it. Finally, containers that run sshd at all are the bigger problem: an image that needs a debug shell is better served by kubectl exec or an ephemeral debug container, and a distroless base removes the option entirely.

Questions people ask

Is Ubuntu or Debian affected by CVE-2026-123158?

Not through this path. The bypass depends on musl's crypt() returning * for overlong keys, and on sshd running without PAM. Ubuntu and Debian use glibc, build sshd with PAM and ship UsePAM yes. Take the update when your distribution ships it, but the emergency is Alpine and other musl systems with PAM off.

Does disabling root login stop SSHole?

It protects root only, and the default PermitRootLogin prohibit-password already does that. Any other account with * in its password field is still a target: key-only users, directory-service users and the alpine user in tiny-cloud images, which can reach root through doas. Setting PasswordAuthentication no closes the bypass for every account, and patching removes it. Check /etc/shadow for * entries to see which users are exposed.

Do I need to restart sshd after apk upgrade?

Yes. apk upgrade replaces the binary on disk, but the listening daemon keeps running the old code until it restarts. Run rc-service sshd restart, or reboot. In Kubernetes, a pod keeps its image until it is recreated, so rebuild the image on a fixed Alpine release and roll the deployment.

The call we'd make

Treat any Alpine host or image that runs sshd as exposed until apk info -v openssh-server shows the fixed package and the daemon has restarted, and push PasswordAuthentication no everywhere today, since it costs nothing on a key-only fleet. The caveat: CISA has evidence of exploitation, so on hosts that were reachable with passwords on, patching is the start of the work, not the end. Check the logs.

Sources

Explore topics:SecurityNewsLinux
React
Share this post
Cite this article
Plain text

Kiril Urbonas (2026). OpenSSH CVE-2026-123158 "SSHole": A Long Password Logs In on Alpine. Patch by Nov 12. DevOpsNess. https://www.devopsness.com/blog/openssh-cve-2026-123158-sshole-alpine-password-bypass

Markdown

[OpenSSH CVE-2026-123158 "SSHole": A Long Password Logs In on Alpine. Patch by Nov 12](https://www.devopsness.com/blog/openssh-cve-2026-123158-sshole-alpine-password-bypass) (Kiril Urbonas, DevOpsNess, 2026-11-11)

KU

Kiril Urbonas

Founder & Chief Editor

591 articles
View all articles by Kiril Urbonas

You might have missed

Evergreen posts worth revisiting.