Security

sshhole (CVE-2026-123158): Who Is Really Affected by the OpenSSH Bypass

Back to Blog
A modern alternative to cPanel, Plesk and CyberPanel — isolated, secure, AI-assisted.
Start free

Short answer: CVE-2026-123158, nicknamed sshhole, lets a remote attacker log in over SSH without knowing any password by sending one that is absurdly long. It only works where sshd is linked against musl libc and runs without PAM, which in practice means Alpine Linux and Alpine-based container images. Servers on glibc distributions such as AlmaLinux, Rocky Linux, Debian and Ubuntu are not affected, and neither is any sshd that authenticates through PAM. The fix is OpenSSH 10.6p2, released on 5 November 2026. One command tells you where you stand, and it is in the section below.

8.1
CVSS v3.1 base score, rated high severity
10.6p2
first fixed Portable OpenSSH release, published 5 November 2026
256
bytes: the password length above which musl's crypt() starts returning an error marker
musl only
glibc builds and any sshd using PAM are outside the affected class

What the Bug Actually Is

When sshd checks a password without PAM, it hashes what the client sent and compares the result with the hash stored for that account. The comparison is a string comparison, which is fine as long as the hashing function always returns a hash.

musl libc's crypt() does not. Given a key longer than 256 bytes it refuses to hash at all and returns the single character * as an error marker. That character is also what Linux stores in the password field of an account that must never accept a password: a key-only user, a service account, or Alpine's own root entry. So when an attacker sends a password of a few hundred bytes against such an account, sshd compares * with *, the strings match, and the login is accepted.

In other words, the accounts that were deliberately marked as having no usable password are exactly the accounts an attacker can walk into. That is what makes this bug interesting rather than merely bad.

Why a Second Account Has to Exist

There is one more condition, and it comes from a feature. Since 2016, OpenSSH has deliberately spent time hashing a password even when the target account has no valid hash, so that an attacker cannot tell valid usernames from invalid ones by measuring response times. To do that it borrows hashing settings from another account that does have a real hash. On a musl system without PAM, that borrowed path is what produces the * return value for the oversized input. If no account on the machine has a real password hash, the mechanism has nothing to borrow and the bypass does not trigger.

This is worth stating plainly: the anti-enumeration defence is not the flaw. The flaw is a libc function that returns a value which happens to be a valid stored secret.

Who Is Affected, and Who Is Not

SetupAffectedWhy
Alpine Linux with the default openssh-serverYes, before the patched Alpine buildsmusl libc, PAM not used by default, password authentication on by default
Alpine-based container or appliance image that runs sshdYes, unless rebuilt on a patched baseSame conditions inside the image
Debian, Ubuntu, AlmaLinux, Rocky Linux, RHEL, FedoraNoglibc, and sshd authenticates through PAM
Any sshd built against musl but configured with UsePAM yesNoPAM does the password check, so OpenSSH's own comparison is never reached
Any server with PasswordAuthentication noNoThe vulnerable code path requires a password attempt
OpenSSH 10.6p2 or laterNoStored hashes shorter than four characters are now rejected outright

Root deserves a note. Alpine ships PermitRootLogin prohibit-password, so the default root entry is not directly reachable even though its stored field is *. The accounts that matter in practice are the ordinary key-only users: the deploy user, the backup user, the CI user, the account you created with an SSH key and no password precisely because that felt safer.

Check Your Own Server in One Command

Ask sshd what it is actually running with, rather than reading the config file. The effective configuration is what counts, because an Include or a Match block can change it:

sshd -T | grep -i -E 'passwordauthentication|usepam|permitrootlogin'

If that prints passwordauthentication yes together with usepam no, move on to the libc question:

# Which libc does sshd link against?
ldd "$(command -v sshd)" 2>&1 | head -5

# musl systems print a line containing ld-musl; glibc systems print libc.so.6
ldd "$(command -v sshd)" 2>&1 | grep -c musl

# Which OpenSSH version is installed?
sshd -V 2>&1 | head -1

Three yes answers put you in the affected class: musl, no PAM, and an OpenSSH older than 10.6p2. Anything less than all three and the bypass does not apply to that host.

To see which accounts would be the targets if it did, list the local users whose password field is a single marker character:

awk -F: '$2 == "*" || $2 == "!" || $2 == "" {print $1, "->", ($2 == "" ? "(empty)" : $2)}' /etc/shadow

How to Fix It

  1. Update OpenSSH. On Alpine, apk upgrade -U openssh followed by rc-service sshd restart. Alpine backported the fix across its supported branches, so you do not have to jump releases to get it.
  2. If you cannot patch immediately, turn off password authentication. Set PasswordAuthentication no in sshd_config and restart sshd. On a server that already uses SSH keys this costs nothing and closes the path completely.
  3. Rebuild your container images. An image you built last month still contains last month's OpenSSH. Patching the host does not touch it.
  4. Then look back through the logs. The signature of a successful attempt is an accepted password for an account that has no password. On Alpine that lives in /var/log/messages:
    grep 'Accepted password' /var/log/messages | awk '{print $NF, $0}' | sort -u
    Compare the usernames against the list from the awk command above. Any overlap deserves a real investigation, starting with ~/.ssh/authorized_keys for that account and the crontabs it owns.

Does This Affect a Panelica Server?

No, and the reason is structural rather than lucky. Panelica is built and tested against nine glibc distributions: AlmaLinux 9 and 10, Rocky Linux 9 and 10, Debian 12 and 13, and Ubuntu 22.04, 24.04 and 26.04 LTS. Every one of them ships an sshd that is linked against glibc and authenticates through PAM, which places them outside the affected class on both counts. There is no Alpine or musl variant of the panel to patch.

Where Panelica operators should still look is one layer up, at what runs on the server:

  • Alpine-based containers. If you host Docker applications and any of those images run sshd, they need the patched Alpine base. A container does not inherit the host's OpenSSH.
  • Isolated environments. If you hand customers full root in an isolated Linux environment and they chose an Alpine template, that environment has its own sshd and its own patch state. Its SSH exposure is theirs to manage, but it is your port.
  • Key-only accounts in general. Panelica creates SSH access per account in two shapes, an SFTP-only jail and a full chrooted shell, and the panel lets you keep those accounts key-based. That is still the right default. The lesson of sshhole is not that key-only accounts are risky; it is that password authentication should be off on hosts where nobody authenticates with a password.

If you run hosting on a mixed estate and cannot easily answer "which of my servers still accept SSH passwords", that is the more useful question to solve than this one CVE. A panel that shows SSH access per account and per server across every machine you manage turns that from an audit into a glance. See how Panelica manages SSH access across your servers.

The Wider Lesson for Anyone Packaging Software

This bug needed three ordinary decisions to line up: a libc that signals an error with a return value instead of a null, a stored secret format that uses the same character, and an anti-enumeration feature that reaches into a second account to look busy. Each one is defensible on its own. The failure appeared where they met, which is why it survived in a widely deployed configuration for so long.

The practical takeaway for operators is less philosophical. Know which libc your security-critical binaries link against, know whether PAM is in the path, and keep a list of the accounts on your machines whose password field is a marker rather than a hash. All three are one-line commands, and all three are the kind of thing you want to have written down before the next advisory lands.

Frequently Asked Questions

What is CVE-2026-123158 (sshhole)?

It is an authentication bypass in OpenSSH before 10.6p2. On systems where sshd is linked against musl libc and does not use PAM, sending a password longer than 256 bytes makes musl's crypt() return the character *, which matches the stored password field of accounts that are not supposed to accept passwords at all, so the login succeeds. It carries a CVSS v3.1 score of 8.1.

Is Debian or Ubuntu affected by sshhole?

No. Debian and Ubuntu use glibc, and their sshd authenticates through PAM. Either condition alone is enough to keep the vulnerable comparison out of reach. The same applies to AlmaLinux, Rocky Linux, RHEL and Fedora.

Which OpenSSH version fixes CVE-2026-123158?

Portable OpenSSH 10.6p2, released on 5 November 2026. It rejects stored password hashes shorter than four characters, so a one-character marker can never match a hashing result. Distributions that backported the fix carry it in their own package versions.

How do I check whether my server is vulnerable?

Run sshd -T | grep -i -E 'passwordauthentication|usepam' and ldd "$(command -v sshd)" | grep -c musl. You are only in the affected class if password authentication is on, PAM is off, sshd is linked against musl, and the OpenSSH version is older than 10.6p2.

Does disabling password authentication protect me?

Yes, completely, for this vulnerability. The vulnerable code runs only during a password authentication attempt. Setting PasswordAuthentication no and restarting sshd is a valid stopgap on key-based servers, and a good permanent setting regardless.

Are Alpine containers affected even if the host is patched?

Yes, if the image runs sshd and was built on an unpatched Alpine base. Containers carry their own copy of OpenSSH and their own libc. Rebuild the image on a patched base and redeploy; updating the host changes nothing inside it.

Which accounts are at risk on an affected system?

Accounts whose password field in /etc/shadow is a single marker such as *, which is how key-only users and service accounts are normally stored. At least one other account on the machine must have a real password hash for the bypass to trigger. Alpine's root account is additionally protected by PermitRootLogin prohibit-password in the default configuration.

Related Reading on panelica.com

Security-first hosting panel

Stop bolting tools onto a legacy panel.

Panelica is a modern, security-first hosting panel — isolated services, built-in Docker and AI-assisted management, with one-click migration from any panel.

Zero-downtime migration Fully isolated services Cancel anytime
Share:
Isolation, native.