CyberPeople

OpenSSH 'sshole' Vulnerability: How a Long Password Opens Passwordless Access on Alpine Linux

OpenSSH 'sshole' Vulnerability: Passwordless Login on Alpine

CVE-2026-123158 ('sshole'): on OpenSSH on musl systems (Alpine), you can log in without a password. Already exploited — how to check and update.

On November 5, 2026, the OpenSSH project released an out-of-cycle update, 10.6p2, closing an authentication-bypass vulnerability — CVE-2026-123158, which researchers named "sshole." The issue was found and reported on November 4 by researcher Özgün Kültekin of Wakefield. It affects systems on musl libc without PAM — primarily Alpine Linux, a distribution that, thanks to its compactness, has become the de-facto standard for Docker containers and embedded systems.

The essence is frightening in its simplicity: an attacker can log into an account that has no password set at all over SSH by simply sending a very long password — from 257 to 1024 bytes. There's no cryptography break here: the cause is a quirk in the musl libc library that hasn't changed since 2012. OpenSSH itself rated the vulnerability critical, and MITRE assigned CVSS 3.1 score 8.1 (High) with vector AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H: the attack goes over the network, requires no prior privileges, and leads to full compromise.

Who's at risk

The vulnerability doesn't affect all systems, but the affected circle is wider than it seems. You're vulnerable if these conditions are met simultaneously:

  • you run openssh-server from Alpine Linux (built without PAM) or openssh-server-pam with UsePAM no;
  • sshd has password authentication enabled (PasswordAuthentication yes — the default);
  • the machine has an account whose shadow password field is * — normal for "key-only" accounts, service accounts, and users from directory services via musl-nscd (nslcd, winbind, sssd);
  • the machine has at least one other account with a real $5$ or $6$ hash.

One user with a password makes all passwordless accounts reachable. A nuance is that root in base Alpine images since version 3.16 also has the * field — but by default PermitRootLogin prohibit-password protects it. The real risk is indirect root access: in official AWS and Azure cloud images (tiny-cloud versions 3.18.11–3.24.3), the alpine user has * and passwordless doas, meaning login under it effectively means root. glibc distributions — Debian, Ubuntu, RHEL, Fedora — as well as systems with PAM, Dropbear, and OpenBSD don't have this problem.

How the vulnerability works: one character with two meanings

To understand the mechanism, let's break down how sshd checks a password without PAM. The daemon takes the entered password, computes its hash via the crypt() function, and compares the result with the string in the shadow file. If the strings match — access is granted. The problem is that the * value has two different meanings in this chain.

Since 2012, crypt() in musl, when it can't process input, returns not NULL like other libraries but the string *. At the same time, musl's SHA-256 and SHA-512 implementations refuse to hash passwords longer than 256 bytes. And since 2016, sshd (to close another vulnerability, CVE-2016-6210 — username enumeration by response time) learned to "borrow" a salt from another account if the target account's password field is too short. The attack chain looks like this:

  1. The attacker sends a password 257 to 1024 bytes long.
  2. crypt() refuses to hash such a long string and returns *.
  3. sshd compares this * with the target account's password field, which holds exactly *.
  4. The strings match — authentication passes.

In other words, it's a classic "error vs. sentinel value" collision: the returned error indicator * matched the sentinel * that means "no password." OpenSSH 10.6p2 closes the path at the sshd level, rejecting stored hashes shorter than four characters.

There's also a more exotic variant: if the first hash sshd finds is bcrypt ($2b$), sshd copies only the $2b$10$ prefix without the salt, musl considers such a string invalid and returns * for any password — then even a short one works. On Alpine, bcrypt is rare, but it happens when hashes are generated elsewhere and copied into the shadow file. Another nuance worth knowing for scanners: a successful login requires two password attempts within one TCP connection — the first attempt always fails due to an internal buffer overwrite, the second passes. So a scanner that sends one password per connection wrongly marks vulnerable hosts as clean.

SSH server terminal

First in-the-wild attacks

If at first it seemed there was time to update, the very next day disproved it. On November 6, Previdian's threat-intelligence founder Ryan Dewhurst reported that the firm's sensors recorded real attacks, and at least one of them succeeded.

"Our first recorded attempt came in less than nine hours after the CVE was published, and we confirmed successful root access on a Previdian honeypot running genuine Alpine Linux and OpenSSH," he told Help Net Security. The attacking address 89.116.89[.]18 (Japanese hosting) used oversized passwords and ran reconnaissance commands id, uname, and hostname via non-interactive SSH sessions. In total Previdian counted eight attempts — all from one address and all caught by a single sensor.

The company added CVE-2026-123158 to its own known-exploited-vulnerabilities list, although CISA hasn't added it to its KEV catalog yet. Proof-of-concept exploits have already appeared on GitHub, but Previdian warns they're unverified and may contain malicious code. OpenSSH developer Damien Miller urged immediate action on Mastodon: "Stop reading and turn off PasswordAuthentication or SSH for these systems NOW."

Why this is serious: containers, routers, and 'docker images you've pulled'

At first glance the topic may seem narrow — "just Alpine Linux." But Alpine is the base image for a huge number of containers worldwide: from microservices to CI/CD runners. If a container raised from Alpine runs sshd with password authentication, it's vulnerable. Kültekin himself lists among musl systems worth checking: OpenWrt, Buildroot, and Yocto, as well as — literally — "a bunch of Docker images you've pulled."

A separate case is routers. In OpenWrt, the openssh-server package is built on musl without PAM and uses upstream configuration with PasswordAuthentication yes and AllowTcpForwarding yes. Once root has a password (as on almost every configured router), the service accounts daemon, network, and nobody (with the * field and /bin/false shell) can be bypassed and used as a tunnel into the local network. Important: OpenWrt uses Dropbear by default, which is not vulnerable — the problem arises only if the administrator installed OpenSSH themselves.

How to check if you're vulnerable

The most reliable way is to check the actual configuration rather than rely on the package version. First, look at how your sshd runs:

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

The system is not vulnerable if password authentication is disabled or PAM is enabled. Second, check for "target" accounts and a real hash:

awk -F: '$2=="*"{print $1}' /etc/shadow
awk -F: '$2 ~ /^\$[56]\$/{print $1}' /etc/shadow

If the first command outputs accounts other than root (or root with PermitRootLogin yes), and the second outputs at least one account, the host is exploitable until patched. Pay special attention to Alpine: patched packages keep old version numbers (for example, 10.3_p1, not 10.6), so scanners that only compare the version to the 10.6p2 threshold wrongly mark patched hosts as vulnerable. Check against Alpine package versions for your branch.

How to protect yourself and detect a breach

The most important thing is to update and, critically, restart the sshd daemon. Updating the package alone doesn't replace the running process: the old code keeps running until sshd is restarted.

  1. Update packages: apk upgrade -U -a.
  2. Restart the service: rc-service sshd restart.
  3. If updating isn't possible yet — disable password authentication (PasswordAuthentication no in sshd_config) and restart sshd. This is reliable temporary protection, since the attack goes precisely through the password path. First make sure key-based login works.

Fixed openssh versions for Alpine branches: 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, 3.16 — 9.0_p1-r6. For other systems — update to OpenSSH 10.6p2 or newer. Containers should be rebuilt from fixed base images, not just restarted.

If you can't disable password authentication for some reason but need protection now, there's another temporary trick: replace the * value in the target account's shadow field with a longer placeholder that doesn't start with ! (for example, *NP*). Then the field is no longer single-byte, sshd no longer "borrows" a salt, and musl returns a normal string that never matches — key-based login continues to work. This can be done with, for example, echo 'alpine:*NP*' | chpasswd -e, but only as a supplement to PasswordAuthentication no and as a bridge until the patch is installed.

To detect an already-completed breach, SOCRadar advises searching /var/log/messages (and archives) for Accepted password for entries for passwordless account names — alpine, root, key users — as well as reviewing doas usage history, recently created users, and authorized_keys files. If a suspicious login can't be ruled out, the machine should be considered compromised.

SSH security

Response speed in the AI era

The "sshole" story is also telling in how it was found. Kültekin built sshd in every possible combination and ran about 17,600 non-standard login attempts through it — and, by his own admission, not alone: "I had swarms of agents. Lots of them. Let's not talk about it." Only the musl build without PAM turned out to be vulnerable.

This is part of a broader trend. OpenSSH maintainers now avoid long embargoes because AI tools re-discover bugs they already know — sometimes within hours. And on the attackers' side, per Dewhurst, attackers are getting faster precisely thanks to AI: "This vulnerability was trivial to exploit, which significantly shortened the time window." The race between patch and exploit is now measured in hours, not weeks.

Server security

Conclusion

CVE-2026-123158 is a reminder that critical vulnerabilities can hide for years at a "low level" — in the interaction between a system library and a daemon — until someone connects the dots. There's no cryptography break and no complex exploit here: a long string instead of a password is enough. But precisely because of its simplicity and Alpine's ubiquity in container infrastructure, the attack started less than nine hours after publication. So respond immediately: update OpenSSH, restart sshd, and if that's impossible — disable password authentication and switch to keys.

If you're unsure whether your credentials were compromised in previous leaks, check them via the breach check, and to learn about building a career and skills in cybersecurity, read the cybersecurity learning material.

Stay ahead of threats

Weekly cybersecurity intelligence in your inbox. No spam.

CyberPeople contributor