Security· Security Disclosure

OpenSSH's November 2026 Password Authentication Bypass on musl: 10.6p2

OpenSSH 10.6p2 fixes a critical password-auth bypass that lets a remote attacker log in to musl systems without PAM, such as Alpine. No CVE. Who's exposed and what to do.

Atlas Security
Security Advisories
11 min read · 2,354 words
Trevor Fannin@trevorfanninFounder, AtlasSecurity alerts and CVE breakdowns, plus infrastructure and general tech.Followon X (opens in a new tab)

Overview

OpenSSH released 10.6p2 on November 5, 2026 with what its release notes call "a critical security workaround" for a password authentication bypass: on affected systems, a remote attacker can log in over SSH without knowing any password. It affects Linux systems that use the musl C library and run sshd without PAM — Alpine Linux (opens in a new tab) in practice. Where the root cause lies is disputed: OpenSSH says it's "outside sshd" but "exploitable via sshd and can be avoided there," so 10.6p2 avoids it, while musl's maintainer, Rich Felker, says "this is not a bug in musl just an erroneous use by the caller" — though he adds musl will likely change the behavior anyway. Either way, the trigger is how musl's crypt() signals an error, reached through sshd's own password check. No CVE has been assigned, and there is no CVSS score: OpenSSH calls it critical in its release notes, and Alpine's advisory gives no rating of its own. The bug was reported by Özgün Kültekin of Wakefield.

Why it's urgent: sshd is reachable from the network by design, the attack needs one connection with no retries, and the preconditions are ordinary — one account with a password, plus a key-only account whose name the attacker needs, though names like root or alpine are predictable. Alpine is one of the most common base images for containers and small VPS hosts, though most containers don't run sshd. The fix reaches Alpine with a normal upgrade, but the running daemon keeps the flaw until it restarts. Technical details are already public, including the reporter's *sshole write-up (opens in a new tab), so treat internet-exposed hosts as urgent.

Key facts

FieldDetail
IdentifierNone. OpenSSH shipped the fix in 10.6p2; no CVE had been assigned as of 10:00 AM CST, November 5, and neither OpenSSH's notes nor Alpine's advisory carry a CVSS score
SeverityCritical, OpenSSH's own word in its release notes. Alpine's advisory assigns no rating, and no numeric score exists yet
Root causeDisputed. OpenSSH places it "outside sshd" and still blocks it; musl's maintainer says it's "not a bug in musl just an erroneous use by the caller." The collision is in how musl's crypt() signals an error, reached through sshd's password check when it runs without PAM
ImpactA remote, unauthenticated attacker logs in as a key-only account. root is reachable only if PermitRootLogin yes is set, because the default prohibit-password protects it
AffectedA musl system running sshd without PAM, with PasswordAuthentication yes, at least one account whose password field is *, and at least one account with a $5$ or $6$ hash
Fixed inOpenSSH 10.6p2; Alpine packages from 10.6_p2-r0 (edge) down to 9.0_p1-r6 (3.16) — see the table below
Not affectedglibc systems, any system using PAM for password auth, non-Linux systems, and Dropbear
CreditReported by Özgün Kültekin of Wakefield. Fixed by Damien Miller and Darren Tucker; Timo Teräs helped analyze it, and Natanael Copa built Alpine's packages

Who is affected

A machine is affected only when every one of these is true, per Alpine's advisory (opens in a new tab):

  • It uses the musl C library (Alpine and other musl distributions), not glibc.
  • sshd runs without PAM: Alpine's openssh-server package is built without it, and openssh-server-pam is built with PAM but still runs without it when UsePAM no is set. Only openssh-server-pam with UsePAM yes is not affected.
  • PasswordAuthentication is yes, the OpenSSH default.
  • An account exists whose password field is * — the normal marker for an account with no password, such as a key-only user, directory-service users with no shadow entry, and root on Alpine (shipped as root:* since about 3.16).
  • At least one local account has a real $5$ or $6$ password hash. Without one, the bug doesn't trigger.

That last condition is why Alpine's official container image isn't exposed on its own: root is * — we checked 3.21 through 3.24 — and no account has a hash yet. That changes the moment any account gets a password, whether an admin sets one or an image adds a user with a hashed password. Any host with a password hash and a * account meets the condition. Alpine calls out its tiny-cloud images, whose alpine user ships as * with passwordless doas: safe on first boot, exposed as soon as any hash exists, and then an attacker who logs in as alpine can doas to root.

Not affected: glibc systems; systems with PasswordAuthentication no; openssh-server-pam with UsePAM yes; accounts locked with ! (they can't log in at all); machines where no account has a $-style hash; images configured by cloud-init, which writes PasswordAuthentication no; and Dropbear, which hands the stored * to crypt() as the salt directly and so never gets a * back to match (we confirmed this on musl); Felker's advisory also lists Dropbear as unaffected. Containers that don't run sshd aren't affected.

Distribution status

Alpine has published fixed packages for every branch it still updates and for several that it doesn't. As of 10:00 AM CST, November 5:

Alpine Linux

FixedTracker
  • edge
    Fixed
    10.6_p2-r0
    Nov 5
  • 3.24
    Fixed
    10.3_p1-r2
    Nov 5
  • 3.23
    Fixed
    10.2_p1-r1
    Nov 5
  • 3.22
    Fixed
    10.0_p1-r11
    Nov 5
  • 3.21End of support Nov 1
    Fixed
    9.9_p2-r1
    Nov 5
  • 3.16 – 3.20No longer regularly updated
    Fixed anyway
    Down to 9.0_p1-r6 on 3.16Nov 5

The fix installs with a normal upgrade; we confirmed the 3.21 repository now serves the fixed 9.9_p2-r1. Restart sshd afterward; the package upgrade doesn't. See End-of-life versions for 3.16 through 3.21.

Other musl systems

The condition is musl plus sshd without PAM, so it isn't unique to Alpine. Other musl-based systems — Void Linux's musl variant, Chimera Linux, postmarketOS, Buildroot or Yocto images built with musl, and OpenWrt devices that run OpenSSH instead of Dropbear — should check whether they ship sshd at all and, if so, whether PAM is in use, using the checks below. We haven't confirmed a fix state for any of them; watch each project's own advisories. glibc distributions are not affected: Debian, Ubuntu, RHEL and their families, and Wolfi and Chainguard's images, which use glibc rather than musl.

How the vulnerability works

When sshd runs without PAM, it checks a password itself: it runs your attempt through the C library's crypt() function and compares the result to the account's stored password field. An account with no password stores a literal * in that field, which is not a valid hash, so no ordinary password should ever match it.

The flaw is a collision between two unrelated uses of the same *. Alpine's advisory explains that musl's crypt() returns the string * as its error value when the supplied key is longer than 256 bytes. OpenSSH accepts passwords up to 1024 bytes, so an attempt above that 256-byte boundary makes musl's crypt() return * — which is exactly what a no-password account already stores. The computed value and the stored value are both *, they compare equal, and sshd treats the password as correct. Nothing about the account's real credentials is involved; the match is an accident of how musl signals the error — it returns a short string rather than failing with NULL, and here that string equals the stored field. (The one account with a real hash matters because sshd needs a valid salt to hash against for the empty account; beyond supplying that, its password is never used.) We reproduced musl's behavior directly: crypt() returns * for an over-long key only when it's given a real account's salt, which is why the bug needs that second account.

This depends on OpenSSH's particular habit of hashing the attempt against another account's salt, so it doesn't generalize to every password check on musl. Felker's advisory says "Dropbear and other non-OpenSSH software using password-based logins is not affected," which matches our own Dropbear test. OpenSSH blocks it regardless of whose bug it is, and Alpine's stable-branch packages carry a patch for the same problem.

The fix

OpenSSH's change refuses to accept a match when the stored password field is too short to be a real hash. It adds a MIN_PASSWORD_HASH_LEN of 4 and requires the stored field to be at least that long before a comparison can succeed, so a one-byte * can never match whatever crypt() returns. The commit landed on the portable V_10_6 branch on November 4 and shipped in 10.6p2 the next day.

openssh/openssh-portable · 90f9c2f · Nov 4, 2026
auth-passwd.c
13 lines added, 4 removed
openbsd-compat/xcrypt.c
13 lines added, 5 removed
openbsd-compat/port-uw.c
8 lines added, 8 removed
3 files changed34 lines added, 17 removed

Which systems are exposed

What follows is our reading of the conditions in Alpine's advisory and OpenSSH's notes, not a confirmed login path for any one machine.

SetupExposed?
Alpine openssh-server (no PAM), PasswordAuthentication yes, a * account, one hashed accountYes
Same, but no account has a $5$/$6$ hash yetNot yet: the bug needs one real hash present
openssh-server-pam with UsePAM yesNo: PAM handles the password
musl system with PasswordAuthentication noNo: sshd never runs the password check
glibc system (Debian, Ubuntu, RHEL, …), any configNo: the error-value collision is specific to musl's crypt()
root with the default PermitRootLogin prohibit-passwordNot as root directly; another * account that can log in and escalate still exposes the host
Dropbear, or other non-OpenSSH SSH serversNo: Felker's advisory says non-OpenSSH password logins aren't affected, and we confirmed Dropbear

Patch first the musl hosts whose SSH port is reachable from untrusted networks, and any that have both a key-only account and an account with a password.

How to check your systems

A host's sshd and a container's sshd are separate, so check each one that runs it. We tested these in the official Alpine 3.21 image.

Check your C library and PAM

Shell
ldd --version 2>&1 | head -1        # "musl libc ..." means musl; "GLIBC" means glibcsshd -T | grep -i usepam            # "usepam yes" = not affected; no line or "usepam no" = PAM not in usesshd -T | grep -i passwordauthentication

On Alpine's default openssh-server, ldd reports musl libc, sshd -T prints no usepam line at all (it was compiled without PAM), and passwordauthentication yes unless you changed it — the exposed combination. The openssh-server-pam package with UsePAM no prints usepam no: PAM isn't handling the password there either, so it's exposed if the other conditions hold. A usepam yes host is not affected.

Check for the preconditions

Shell
# accounts with no password (field is *), which the bug can log in as:awk -F: '$2 == "*" { print $1 }' /etc/shadow# accounts with a $5$ or $6$ hash, one of which the bug needs present:awk -F: '$2 ~ /^\$[56]\$/ { print $1 }' /etc/shadow

Run these as root. If the first list is non-empty and the second is too, the machine meets the conditions. In Alpine's official container image the second list is empty, which is why it isn't exposed until an account gets a password. One caveat: users that come from a directory service (via musl-nscd — nslcd, winbind, sssd) have no /etc/shadow entry, so this awk won't list them even though they count as * accounts.

How to fix

Update and restart sshd

On Alpine:

Shell
apk upgrade -U -arc-service sshd restartapk list --installed | grep -E '^openssh'   # confirm the version (covers openssh-server-pam too)

Alpine 3.21.10, 3.22.8, 3.23.8 and 3.24.4 carry the fixed package; the fixed versions per branch are in the table above. The restart matters: upgrading the package does not replace the running daemon, so sshd keeps the flaw until rc-service sshd restart. Rebuild container images on a fixed base, and rebuild anything built on alpine that runs sshd. If you build OpenSSH yourself, move to 10.6p2.

If you can't patch immediately

Turn off password authentication. This closes the hole on its own, because sshd then never runs the broken check:

Shell
mkdir -p /etc/ssh/sshd_config.decho 'PasswordAuthentication no' > /etc/ssh/sshd_config.d/00-no-passwords.confsshd -t && rc-service sshd restartsshd -T | grep -i passwordauthentication   # should print: passwordauthentication no

Alpine reads sshd_config.d from 3.19 onward; on older releases, set PasswordAuthentication no in /etc/ssh/sshd_config itself. Before you restart, make sure your key-based login already works and keep your current session open until you've tested a new one. Alpine's advisory has a longer sed recipe that also rewrites PasswordAuthentication yes lines inside Match blocks.

Check for signs of compromise

Alpine's advisory gives a forensic check. In /var/log/messages, look for sshd lines reading Accepted password for an account that has no password — root, the cloud images' alpine user, or any key-only user:

Shell
grep 'Accepted password' /var/log/messages

A password login for an account stored as * should be impossible, so one is a red flag. Review recent doas use, newly created users, and added authorized_keys on exposed hosts. If you can't rule a login out, treat the machine as compromised.

End-of-life versions

Alpine 3.21 reached end of support on November 1, 2026, and 3.16 through 3.20 are older still. Alpine published fixed openssh packages for all of them anyway, down to 9.0_p1-r6 on 3.16, so an apk upgrade plus an sshd restart fixes those hosts too. They remain unsupported for everything else; plan the upgrade to a current release.

Timeline

All times are US Central: CST (UTC−6).

  • Fix
  • Advisory or rating
  1. Nov 5
    1. 9:07 AMmusl's maintainer posts an advisory calling it "not a bug in musl just an erroneous use by the caller," and confirms Dropbear and other non-OpenSSH software aren't affected

    2. OpenSSH releases 10.6p2 with the workaround, and Alpine publishes its advisory and fixed packages for every branch back to 3.16

  2. Nov 4
    1. 5:57 PMThe portable tree's version is bumped to 10.6p2

    2. 3:58 PMOpenSSH commits the workaround, "avoid password authn bypass," to the portable 10.6 branch

  3. Oct 6
    1. OpenSSH 10.6/10.6p1 is released, without the fix

The notes carry the same statement OpenSSH has run since its October 6 release about why it's now shipping fixes faster: it has seen "a number of cases where a security bug identified by AI tools is subsequently independently discovered by a different researcher," which "suggests that adversaries who do not report bugs to OSS projects are likely to be able to discover these bugs too," so the team "will, for now, be making more frequent releases to get bugfixes into users' hands more quickly rather than batching them." This release is an instance of that: the fix was committed on November 4 and released the next day.

Updates to this post

We'll revise this post and mark it updated when any of these change: a CVE is assigned or an NVD entry appears; another musl distribution (Void, Chimera, postmarketOS, or a Buildroot/Yocto/OpenWrt build) publishes its own status; or a confirmed report of exploitation in the wild appears.

Get help

SSH is the account that reaches everything else, so it's worth knowing which of your hosts expose it and what else is listening. Our free security audit checks the domains and public IPs you verify for exposed services, publicly visible software versions with known CVEs, TLS, email security, DNS, and HTTP headers.

Atlas Service
Free Security Audit
Non-destructive checks of your verified domains and public IPs, and a PDF report with every finding ranked and a fix for each, within 3 business days of verification.

It's the second SSH disclosure we've covered in a month. The other was Tailscale's SSH and Serve vulnerabilities, also fixed without CVEs.

Sources

Atlas Security
Security Advisories

The Atlas security byline: write-ups of vulnerabilities in widely deployed software — what changed, who is exposed, and what to check — verified against primary sources.

Continue reading

More from the Atlas Meridian

Security
13 min read

APT's November 2026 Download Verification Bypass: CVE-2026-109518

An APT flaw lets an on-path attacker swap a verified package and run code as root on Debian, Ubuntu, and derivatives. Debian and Ubuntu have fixes out.

Atlas Security
Security Advisories
View category
Security
15 min read

Rails' November 2026 Active Storage File Write and Read: GHSA-f3w6-w445-fwh9

Rails 8.1.4.1 and 8.0.5.2 fix a Critical (CVSS 9.8) Active Storage flaw: an uploaded image can make ImageMagick write, and read, files on the server.

Atlas Security
Security Advisories
View category
Security
20 min read

WordPress's October 2026 Upgrade RCE and Stored XSS Fixes: WordPress 7.1.4

WordPress 7.1.4 fixes 22 vulnerabilities, including an RCE during core updates and stored XSS, with no CVEs. Who's exposed, how to check, and what to block.

Atlas Security
Security Advisories
View category
Engage · Atlas Engineering

Reading is one thing. Shipping is another.

If this writeup resonates with what you're building, let's talk. We'll connect you directly with an engineer to assist.