- What happened: OpenSSH 10.6p2 release notes fix a password authentication bypass in sshd on some Linux systems.
- Who is affected: sshd on musl libc with PAM disabled and password logins on, per the sshole research write-up.
- What to do now: upgrade to 10.6p2, or turn password authentication off until you can.
- Interview angle: fail-open errors, locked accounts and library contracts.
OpenSSH 10.6p2, released on 5 November 2026, works around a password bypass on Linux systems that use musl libc with PAM disabled. Accounts that should never accept a password can be reached with one. Upgrade, or disable password authentication, then review your logs.
Fail-open describes a system that grants access when something goes wrong. A fail-closed system denies access on errors. Authentication code should always fail closed, because an attacker can often trigger the error path on purpose.
What changed and who is affected?
The OpenSSH project shipped 10.6p2 on 5 November 2026. Its OpenSSH 10.6p2 release notes describe a password authentication bypass in sshd on some Linux systems built with PAM disabled. They say the root cause lies outside sshd but can be avoided there.
The independent sshole research write-up gives the detail. It says the flaw has existed since 2016 and affects musl-based systems such as Alpine, OpenWrt, Buildroot and Yocto. That page is a single researcher’s account, and I could not find a second source or a CVE for it, so treat its claims as reported, not confirmed.
| Item | Detail | Source |
|---|---|---|
| Fixed release | OpenSSH 10.6p2, 2026-11-05 | OpenSSH 10.6p2 release notes |
| Affected build | sshd on musl libc, PAM disabled | OpenSSH 10.6p2 release notes |
| Affected accounts | Any account with * in the password field | sshole research write-up |
| Not affected | glibc with PAM, Dropbear, OpenBSD | sshole research write-up |
| CVE | None cited at time of writing | sshole research write-up |
The write-up also says Alpine’s official AWS and Azure images have a default user with passwordless doas. On those images, a login as that user is effectively a route to root.
How does the bypass work?
Two sound design choices combine badly. The summary below stays at advisory level.
- Locked accounts store * in the shadow password field. It is not a valid hash, so nothing should match it.
- musl’s crypt() returns * when it fails. A musl commit (2012) changed this from the older null return, and its musl SHA-512 crypt commit rejects over-length passwords this way.
- sshd compares the returned value with the stored field. Failure and the locked placeholder look identical, so the comparison succeeds.
- With PAM enabled, crypt() is never called for a * entry, which is why those setups are not affected.
Alpine also set root’s password field to * from release 3.16, per this Alpine aports commit. That is a sensible hardening step, and it is also what turned root into a locked account the bug could reach.
Here is the safe pattern. The fix is to treat the error as an error:
/* Unsafe idea: error value flows into the comparison */
result = crypt(input, stored);
ok = (strcmp(result, stored) == 0);
/* Safer idea: reject locked entries first, check for failure */
if (stored[0] == '*' || stored[0] == '!') return DENY;
result = crypt(input, stored);
if (result == NULL || result[0] == '*') return DENY;
ok = (constant_time_equal(result, stored));
What should developers do right now?
- Detect: check whether sshd links against musl, whether UsePAM is on, and whether PasswordAuthentication is enabled.
- List locked accounts: find shadow entries with * and confirm none should accept logins.
- Patch: upgrade to OpenSSH 10.6p2 or later. On Alpine the write-up gives apk upgrade openssh.
- Mitigate: if you cannot upgrade yet, set PasswordAuthentication no in a drop-in file and restart sshd. Verify your key login works first.
- Verify: confirm the effective configuration with sshd -T and the installed version with ssh -V.
- Review logs: look for successful password logins on accounts that should be key-only, then for unexpected sessions or privilege escalation afterwards.
The write-up links a compromise-check repository. Read its code before running anything on a production host. Rate limiting and alerting on SSH also help; see our rate limiter design guide.
Interview questions this update prepares you for
Why does a locked account use * in the password field?
A locked or key-only account stores a value that can never be a valid password hash, and * is the common choice. Any hash comparison against it should fail, so password login is impossible. The design relies on one assumption: the verification routine never produces the same string for an input. This question tests whether you understand that authentication is a comparison, and comparisons are only as safe as both operands.
Follow-up they may ask: What is the difference between a locked account and one with an empty password?
What is fail-open versus fail-closed behaviour?
Fail-closed means an error denies access; fail-open means an error grants it. Here an error value from the crypt routine matched the stored placeholder, so a failure looked like a success. Secure code treats errors as a distinct signal, not as ordinary data that flows into a comparison. Return explicit status codes or exceptions, and never let an error value share a type and format with a legitimate result.
Follow-up they may ask: Where else have you seen errors collapse into valid values, such as sentinel values like -1 or empty strings?
Why does a library behaviour change cause a bug years later?
Callers encode assumptions about a dependency. The musl commit (2012) changed what the function returns on failure, and older callers had assumed a null return. Nothing broke in tests on glibc, so the mismatch stayed hidden. This is why you read the contract of every dependency you swap, and why portability testing across libc implementations matters for security code.
Follow-up they may ask: How would you test the same code against two different libc implementations in CI?
What does defence in depth mean for SSH?
No single control should decide who gets in. Disable password authentication where keys suffice, restrict users with AllowUsers, limit exposure with network rules, add rate limiting and alerting, and give default accounts the least privilege they need. The same layering applies in application code, as in these authentication mistakes for web apps.
Follow-up they may ask: Which of these controls would have limited the damage of this bug, and why?
How do you decide between patching and a config workaround?
Patch when a vendor fix exists, because it removes the cause. Use a workaround when you cannot deploy immediately, but treat it as temporary and track it. Verify the workaround took effect, for example by checking the effective sshd configuration, and set a deadline to upgrade. Document the exposure window so you can review logs for it afterwards.
Follow-up they may ask: How do you verify that a configuration change actually reached the running daemon?
The NexGismo verdict: This bug is a clean lesson in why error values must never look like valid data. My recommendation: disable password authentication on every SSH host that does not truly need it, and treat it as the baseline, not a workaround.
- OpenSSH 10.6p2 was released on 5 November 2026 to address a password bypass on musl systems.
- The reported issue needs musl libc, PAM disabled, and an account with * as its password field.
- glibc systems using PAM are reported as not affected.
- No CVE was cited by the researcher or the release notes at the time of writing.
- Turning off PasswordAuthentication is the reported interim mitigation.
Frequently Asked Questions
Is OpenSSH 10.6p2 a critical update?
The OpenSSH 10.6p2 release notes call it a critical security workaround for Linux systems using musl libc with PAM disabled. If your sshd is not built that way, you are not in the affected group, but upgrading is still sensible.
Does the OpenSSH musl bug affect glibc systems?
According to the sshole research write-up, glibc systems that authenticate through PAM are not affected, and neither are Dropbear or OpenBSD. Confirm your own build rather than assuming.
How do I stop the sshd password bypass without upgrading?
The researcher’s interim advice is to set PasswordAuthentication no in an sshd drop-in file and restart sshd. Key-based logins keep working, so confirm your own key access first to avoid locking yourself out.
Has this OpenSSH flaw been assigned a CVE?
The research page cites no CVE for this bug, and the release notes do not list one. Treat any CVE number you see elsewhere with caution until it appears in an official advisory.
Small design decisions made years apart can combine into a serious hole. Patch your musl-based hosts, close the password path where you can, and use this bug to practise explaining fail-open behaviour. For more on privilege boundaries, read our least-privilege thinking guide for Node.js.
