"An attacker who can reach your SSH port can log in without knowing any password. It takes one connection, works every time, and needs no retries." — Alpine Linux security advisory, November 5, 2026

The short version, for people who run a website rather than a server farm: this is a bug in the hosting layer, not in WordPress or your shop software, and most readers are not on the affected stack. I say which stacks are clear before I say anything urgent, because that part is true and it should come first.

On November 5, 2026, the OpenSSH team shipped version 10.6p2 for one reason. Not features, not performance — a single security workaround for Linux systems that use the musl C library (a small alternative to the standard Linux C library, popular where size matters) with PAM, the pluggable authentication module most servers use, switched off. The Alpine Linux team published an advisory the same day, and the wording was blunt: reachable SSH port, no password needed.

Four days later, CISA added the flaw to its Known Exploited Vulnerabilities catalog — the list of bugs that have been used in real attacks rather than only demonstrated in a lab.

That sequence — patch, advisory, exploitation, federal deadline — is now routine enough that it mostly reads as noise. What makes this one worth your time is the part that gets lost in the bulletins: the accounts that broke were the ones somebody had deliberately locked. The safety measure was the way in.

What actually happened

Stripped to dates:

  • 1980 — Unix starts marking an account that must never accept a password by putting a single * in the password field. The researcher who worked this bug out traces the convention to Bill Joy's 3BSD password file, where the daemon account carries exactly that character. It survived into /etc/shadow, and hardening guides still tell you to use it.
  • August 2012 — musl, the C library Alpine is built on, changed its password-hashing function so that a failure returns that same single character * instead of a null result, on the reasonable grounds that programs which forget to check for null were crashing. Twenty days later, the same library added a rule that refuses to hash anything longer than 256 bytes — a denial-of-service guard — and returns * for that too.
  • 2016 — OpenSSH closed a timing side channel (CVE-2016-6210) that let an attacker work out which usernames existed on a server. The fix made sshd do the same amount of work for accounts that exist and accounts that do not.
  • October 30, 2026 — a security review landed a fix in OpenSSH's salt-handling function. The bug sat four lines further down.
  • November 5, 2026 — OpenSSH 10.6p2 was released. Alpine shipped patched packages the same day for every branch back to 3.16. The CVE record was published.
  • November 6, 2026 — Previdian, a threat intelligence firm, recorded the first exploitation attempt, less than nine hours after publication. One of its honeypots — a deliberately exposed server whose only job is to be attacked and watched — was logged into as root.
  • November 9, 2026 — CISA added CVE-2026-123158 to the KEV catalog with a three-day remediation deadline for federal agencies.
  • November 10, 2026 — Previdian's public tracker showed 22 attempts from 14 addresses in 10 countries across four sensors.

The version numbers matter less than the pattern, so let me show you the pattern.

How a lock became a key

For four decades, Unix and its descendants have marked an account that must never accept a password with a single asterisk. No password hash begins with *, so nothing you type can ever match it. That is the entire design, and it is why a locked account is a safe account.

In 2016, OpenSSH made that design slightly more complicated in the name of security. When sshd is built without PAM, it checks a password by hashing what you typed with the salt stored next to the real hash and comparing the results. That works for a normal account. For an account whose field is just *, there is no salt to use — and bailing out early is exactly the timing leak the 2016 fix was closing. So sshd borrows a salt from a different account and does the work anyway. It caches the borrowed salt so the second and later attempts are fast.

Now the collision. Somebody types a password longer than 256 characters. musl refuses to hash it and returns * to say "could not do the job." sshd then compares the * from musl with the * stored for the locked account. The strings are identical. Access granted.

Three separate decisions, spread across forty-six years and two codebases, each defensible on its own terms. The 1980 convention used * to mean "never." The 2012 library used * to mean "I could not." The 2016 fix is what finally pulls both meanings into the same comparison. The comparison function does not read meanings.

The OpenSSH team is explicit that the root cause is not theirs: "We consider the root cause of this bug to be outside sshd, but it is exploitable via sshd and can be avoided there." They shipped the workaround anyway. The fix checks that the stored field is long enough to be a real hash at all, and stops reading through a pointer into the C library's memory that another function could wipe.

One detail that will matter if you are the person deciding whether to panic: sources describe the attempt count differently. Alpine's advisory says it takes one connection and no retries. Medcrypt, which reproduced the bug independently (including on a stock Yocto image), reports two password attempts inside a single connection, because the first one warms the cached salt. Both agree on the part that counts — it is one ordinary SSH session, against a default configuration, with nothing exotic in it. The AC:H in the severity score is scoring that setup requirement, not unreliability; once the conditions exist, the bypass does not fail intermittently.

Who is affected, and who is not

The flaw needs five conditions to line up at once. Drop any one and the chain breaks:

  1. musl libc, not the standard glibc. That means Alpine Linux, Buildroot, Yocto, and a lot of the container images people pull without checking. OpenWrt belongs on the "worth checking" list too, but a stock OpenWrt install runs Dropbear rather than OpenSSH, so it is clear unless somebody added openssh-server on top.
  2. OpenSSH older than 10.6p2.
  3. No PAM in sshd's authentication path. Alpine's default openssh-server is built that way. openssh-server-pam is clear only with UsePAM yes — with UsePAM no it is affected like any other build.
  4. PasswordAuthentication yes, which is the OpenSSH default. Many people never touch it.
  5. At least one account with * in its password field, plus at least one other local account with a real hash. The second half is what makes it work: one person with a password on the box makes every passwordless service account reachable.

That fifth condition is the uncomfortable one. Locking service accounts with * is not a mistake — it is what the hardening checklist tells you to do.

Worth stating precisely, because it separates a scary headline from your actual exposure. Root is locked with * on Alpine, and root can be reached this way when password logins for root are permitted. Upstream OpenSSH's own default, PermitRootLogin prohibit-password, refuses password authentication for root outright — so what your build actually sets is the answer that counts, and sshd -T | grep -i permitrootlogin will tell you. Where that default holds, the sharper risk is indirect: an ordinary *-locked account gets in, then doas or sudo swaps to root without asking for anything, which is how Alpine's cloud images are wired.

So here is the reassuring half, and I want to state it plainly because it is accurate. If you run a website on ordinary hosting, you are almost certainly not exposed. Systems built on glibc — Ubuntu, Debian, Fedora, and every mainstream VPS image built from them — are not affected. Neither are systems where PAM handles authentication, systems running Dropbear instead of OpenSSH, OpenBSD, or containers that do not run an SSH server inside them. Accounts locked with ! rather than * are safe too, as are cloud images configured by cloud-init, which writes PasswordAuthentication no.

Where it does bite:

  • Cheap VPS and container platforms. Alpine's small footprint makes it a common base for budget instances and for the images behind one-click app deployments.
  • Network appliances and embedded kit built on Buildroot or Yocto, where password authentication is usually left on because a technician needs a way in when the keys do not work.
  • Cloud images. Alpine's official AWS and Azure images from 3.18.11 through 3.24.3 ship an alpine user with a * password field and passwordless doas. They are safe on first boot. The moment any real password hash exists on the machine — an admin setting a console password, or user-data creating a user — that unprivileged account becomes root for anyone who can reach port 22.

What to do, in the order that matters

If somebody else runs your server, you have three questions to send them. Copy these:

  1. Does my hosting environment run Alpine or another musl-based system, and does it run an SSH server inside it?
  2. Which OpenSSH version is installed, has it been updated to 10.6p2 or the backported Alpine package, and was sshd restarted afterward? Updating the package does not restart the daemon, and an un-restarted daemon is still the old, vulnerable binary.
  3. Is password authentication enabled for any account, and are any accounts locked with * rather than !?

If the answers are "musl, yes, old, password logins on" — that is your problem to escalate, not to absorb.

If you run your own box, check it yourself. Read-only, nothing changes:

ls -l /lib/ld-musl*                       # a hit means musl; "no such file" means glibc
apk info -v openssh-server                # installed version, on Alpine
sshd -T | grep -i passwordauthentication  # "yes" means condition four is met
sshd -T | grep -i permitrootlogin         # does root accept a password at all?
awk -F: '($2=="*"){print $1}' /etc/shadow                  # locked accounts
awk -F: '($2 ~ /^\$[56]\$/){print $1}' /etc/shadow         # accounts with a real hash

The last two lines are the two halves of condition five. If both print something, all five links are present and you should act today.

On Alpine the fix is apk upgrade -U -a followed by rc-service sshd restart. The restart is not optional. If you cannot patch today, PasswordAuthentication no closes it completely — but confirm your key-based login already works, in a second terminal, before you restart sshd, or you will lock yourself out of your own machine while doing exactly what this article told you to do.

If you genuinely need password logins to stay on, Medcrypt offers a narrower stopgap: MaxAuthTries 1. It holds because the attack needs the second attempt, and note the number — MaxAuthTries 2 is still exploitable. Medcrypt calls it a tourniquet rather than a fix, and Alpine's advisory does not mention it at all, so treat it as a reason to schedule the patch this week, not a reason to skip it.

Then check whether anyone got in. On Alpine, look in /var/log/messages for Accepted password for naming an account that has no password — root, alpine, or any key-only user. Review recently created users, recent additions to authorized_keys, and doas usage on anything internet-facing. If you cannot rule out a login, treat the machine as compromised rather than hoping.

The part worth keeping

Every post like this ends with "patch faster," and you have read that one already. This bug suggests something less comfortable.

Alpine's own advisory is a model of clarity, and it still says "no CVE identifier had been assigned at the time of writing" — the CVE arrived the same day the fix did. The researcher, Özgün Kültekin of Wakefield, built twelve different sshd configurations and threw roughly 17,600 unusual login attempts at them before pinning down the exact combination. Only the musl build without PAM let him through. He credits part of that throughput to AI assistance: "i had agent swarms. a lot of them." OpenSSH's release notes now say the project will ship more frequent releases precisely because bugs that AI tooling finds are being independently rediscovered by other people.

Which brings it back to you and to the one thing you control. You locked the account. You did the hardening step. And on this stack, the lock was the key. That does not mean the hardening was wrong; it means a control is only as good as the code that reads it. "We locked it down" and "we verified it holds" are different sentences, and only the second one is worth anything when a bug like this lands.

Key numbers

Fact Value
CVE CVE-2026-123158 ("sshole")
Severity CVSS 3.1 8.1, AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Weakness class CWE-394, unexpected status code or return value (per the CISA KEV entry)
Fixed in OpenSSH 10.6p2, released 2026-11-05
Alpine branches patched 3.16 through edge; point releases 3.21.10, 3.22.8, 3.23.8, 3.24.4
Password length that triggers it 257 to 1024 bytes
CISA KEV added 2026-11-09, federal due date 2026-11-12
First observed attack under nine hours after publication (Previdian)
Observed attempts, as of 2026-11-10 22 attempts, 14 addresses, 10 countries
Configurations tested by the researcher 12 builds, ~17,600 login attempts, only musl-without-PAM bypassed

The takeaway

Most WardenBit readers are not running this stack and do not need to do anything urgent. The ones who rent Alpine-based VPS instances, run container platforms, or look after an appliance should ask their provider three specific questions and get answers in writing. The rest of us get a durable lesson: the settings you add for safety are code paths too, and a setting nobody has tested against a hostile input is a hope, not a control.

Sources

  • OpenSSH 10.6p2 release notes, 2026-11-05 — openssh.com/releasenotes.html#10.6p2
  • Alpine Linux advisory, 2026-11-05 — alpinelinux.org/posts/2026-11-05-openssh-password-authentication-bypass/
  • Özgün Kültekin's disclosure site, including the 1980 and 2012 history — sshhole.com
  • Medcrypt, independent reproduction on a stock Yocto image — medcrypt.com/blogs/asterisk-hole-cve-2026-123158-when-a-locked-account-is-the-way-in
  • Help Net Security, exploitation report citing Previdian, 2026-11-06 — helpnetsecurity.com
  • Previdian exploitation tracker, read 2026-11-10 — previdian.com/CVE-2026-123158
  • CISA KEV catalog version 2026.11.09 — cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json
  • NVD and CVE.org records for CVE-2026-123158 — nvd.nist.gov, cve.org
Related reading:

A scanner cannot see which C library your host built sshd against — that stays a question for your provider. What a free security scan does cover is the public surface your site exposes, the half you can fix yourself: 40+ automated checks, instant results, no commitment.