Safety#Security scan#Deployment#Linux
OpenSSH rushes out 10.6p2: 257–1,024-byte passwords bypass auth on musl systems
OpenSSH shipped 10.6p2 on November 5: on musl libc systems, 257–1,024-byte passwords authenticate to password-less accounts. Alpine is affected, glibc is not.

OpenSSH issued an emergency 10.6p2 release on November 5, 2026, fixing an authentication bypass reachable through sshd. On Linux systems built against musl libc with PAM support disabled — Alpine, OpenWrt, Buildroot and Yocto among them — an attacker who submits any password between 257 and 1,024 bytes can log in, with the password, to accounts whose shadow entry is *, an account on which no password can be set. That includes key-only accounts. The release notes call it a “password authentication bypass that is exploitable through sshd(8)” when the system is “built and run with PAM support disabled”; OpenSSH rates the issue critical, Alpine has shipped fixed packages for every supported release back to 3.16, and glibc-based systems are not affected.
Key points
- Four conditions stack up, per the Alpine advisory: an sshd built and run without PAM, password authentication enabled (
PasswordAuthentication yesis the default), at least one account whose password field is*, and at least one other local account with a$5$or$6$hash. Alpine’s default build meets the first three — and when all four hold, the attack “succeeds on every try with a single connection.” - The mechanism couples two old changes: musl made crypt() return the error marker
*on failure in 2012 and then capped sha512crypt at 256 bytes; OpenSSH’s 2016 fix for the CVE-2016-6210 timing side channel had sshd borrow another account’s salt. A too-long password fails hashing, returns*, and matches the stored*. - The fix is a workaround on the sshd side: 10.6p2 refuses matches where the stored field is shorter than four characters, and OpenSSH states the root cause lies outside sshd. No CVE has been assigned, and no exploitation has been reported so far.
Background
Nothing new in sshd’s own code caused this; three unrelated decisions collided. On the musl side in 2012, the library made crypt() return * instead of NULL so programs that skip the check would not crash — the discoverer’s write-up puts it as “yep. the star. again.” Twenty days later musl capped sha512crypt at 256 bytes: past that length, crypt fails, and failure returns *. On the OpenSSH side, the 2016 fix for CVE-2016-6210, a username-enumeration timing leak, had sshd hash the submitted password against another account’s salt when there is no real hash to compare — burning the same amount of time — and that path also covers real users whose field is *. On Alpine’s side, around 2022 the distribution moved root’s lock from ! to * so that root’s SSH key logins kept working, which left the default images with root:* in shadow. The discoverer, Özgün Kültekin, chained the three steps into one causal story: “accounts that should never take a password at all … take any password longer than 256 characters.”
The facts
The conditions and the blast radius line up across sources:
| Item | Detail |
|---|---|
| Affected | musl libc systems: Alpine (default build qualifies), OpenWrt (when OpenSSH is installed on top), Buildroot, Yocto |
| Not affected | glibc systems, PAM-enabled builds, hosts with PasswordAuthentication no, containers without sshd, accounts locked with ! |
| Trigger length | 257–1,024 bytes (the ceiling is sshd’s own password limit) |
| Fixed | OpenSSH 10.6p2 (2026-11-05); Alpine point releases 3.21.10 / 3.22.8 / 3.23.8 / 3.24.4, fixes backported to 3.16 |
| Severity | Critical, per OpenSSH; no CVE assigned yet |
| Exploitation | No attacks reported so far |
The accounts to worry about are the password-less ones: key-only accounts, directory-service accounts reached through musl-nscd, and root itself, which Alpine has shipped as root:* since around 3.16 — though The Hacker News notes the default PermitRootLogin prohibit-password blocks root password logins unless an admin changed it. The sharpest edge is the default alpine user in tiny-cloud images (3.18.11–3.24.3): a login there gets passwordless doas, which means full root. The published PoC screenshot shows the whole sequence — a wrong password rejected, then a 257-plus-byte string of A’s accepted, with id printing uid=0(root). OpenWrt’s default Dropbear is unaffected, but devices with OpenSSH installed need checking, and Buildroot and Yocto systems belong on the same list.
What others say
Damien Miller of OpenSSH kept the advice blunt: “set PasswordAuthentication=no or disable SSH for these systems IMMEDIATELY.” He also explained why the team dropped its usual long embargo: long holds now look dangerous, partly because AI agents have recently rediscovered the same bugs within hours — the same trend we covered in OpenAI’s autonomous pipeline that surfaced 948 kernel exploits. The discoverer’s methodology is worth a note of its own: Kültekin (of Wakefield) built sshd across a glibc/musl × PAM/no-PAM × shadow/no-shadow matrix and ran roughly 17,600 unusual login attempts with “agent swarms”; only the musl-without-PAM combination accepted passwords it should not have, which rules out the other paths. Chinese-language coverage matches the numbers: IT Home republished the story on November 6 with the same 257–1,024-byte trigger, the same musl-affected scope and the same package-upgrade fix; the glibc-is-unaffected point comes from the OpenSSH advisory and The Hacker News. On detection, the official advisory and the discoverer agree: an Accepted password for line in the logs against root, alpine or a key-only account means the host is gone.
Fix and detection
On Alpine, the fix is one command plus a restart — upgrading alone leaves the old sshd process running in memory:
apk upgrade -U -a
rc-service sshd restart
If you cannot upgrade yet, confirm key-based SSH works and keep your current session open, then set PasswordAuthentication no, validate with sshd -t, restart, and check sshd -T | grep -i passwordauthentication prints no. For the after-action check, the Alpine advisory says to search /var/log/messages for Accepted password for lines that land on password-less accounts (root, alpine, key-only users), then review doas usage, newly created users, unfamiliar files and authorized_keys. Its wording is blunt: “If you cannot rule out a login, treat the machine as compromised.”
Our take
For teams building on Alpine base images, the lesson is less “patch fast” than “watch your defaults”: three individually reasonable decisions — musl’s crash-safe return value, sshd’s timing-equalizing salt borrowing, Alpine’s choice of root lock — stacked into one critical. Swap out any single leg (glibc, PAM, a ! lock) and the whole thing collapses, which is exactly the checklist to run when triaging. Two honest caveats: the fix is a workaround on the sshd side, and there is no timeline for touching the root cause in musl; and do not over-alert — glibc systems and sshd-less containers are unaffected, so the machines that matter are those running sshd on musl with password logins on. This bug belongs to the same family as IEEE Spectrum’s PHP2Shell post-mortem: a combination planted years ago, waiting for someone who walks that exact path, and — as with PHP’s two CVSS 9.2 RCEs last month — the discovery side is speeding up faster than the response side.
What to watch
Three signals: the CVE assignment and its final description; what musl does about the root cause, given OpenSSH’s “root cause outside sshd” framing and no stated timeline; and when the other musl camp — OpenWrt, Buildroot, Yocto — rolls their own package updates. For operators, Miller’s embargo remark reads as the new normal: the window between discovery and publication keeps shrinking, and password logins are an attack surface you can switch off today.