sshole (CVE-2026-123158): OpenSSH Authentication Bypass on musl Linux
Reporting cutoff: November 6, 2026. This article distinguishes vendor-confirmed exposure, published research and defensive recommendations. It does not report independent exploitation testing or confirmed victim investigations.
An account intended to accept only SSH keys should not suddenly accept a password. Yet that is the failure at the center of CVE-2026-123158, publicly discussed as sshole and presented on the research site sshhole.com. On particular Linux systems using musl libc, OpenSSH's non-PAM password verification can mistake an error result for the stored password field and authenticate a user without the correct credential. [1, 2, 5]
OpenSSH released 10.6p2 on November 5, 2026, describing a critical security workaround for the affected environment. Alpine Linux issued its own advisory and patched packages, including exceptional backports for older releases. Its operational instruction is important: update the server package and restart sshd. Installing the package alone does not restart the running daemon. [1, 2]
This is not a universal break of SSH encryption or public-key cryptography. Exposure depends on the server's C library, authentication path, account state and effective configuration. Those conditions narrow the affected population, but they do not make an exposed server low risk.
What the CVE Establishes
The CVE describes a password authentication bypass in OpenSSH before 10.6p2 on Linux when musl is used without PAM. MITRE, acting as the CVE Numbering Authority, assigns CVSS v3.1 8.1, High, with network reachability, no required privileges and no user interaction. The vector includes high attack complexity. NVD displays that CNA score; it had not supplied a separate NIST assessment when checked for this article. [3, 4]
That score should not be confused with the execution difficulty once the necessary conditions exist. Alpine describes the bypass as reliable in the affected configuration, requiring neither password guessing nor repeated attempts. A configuration-dependent vulnerability can still be straightforward to abuse on a host that meets its prerequisites. [2]
Both OpenSSH and Alpine credit Özgün Kültekin of Wakefield with reporting the issue. The research disclosure describes comparative testing across libc, PAM and password-database configurations, with the unexpected authentication result appearing in the musl, non-PAM combination. [1, 2, 5]
The CVE's CISA enrichment records public proof-of-concept availability. That is different from confirmation of malicious exploitation in the wild. The sources reviewed here do not establish a named intrusion campaign, a victim count or attacker attribution. Public reproducibility increases urgency without justifying invented incident claims. [4]
How an Error Becomes an Authentication Success
In the affected non-PAM path, OpenSSH verifies a password using the system's crypt() functionality and compares the returned value with the account's stored password field. A normal field contains an encoded password hash. Some accounts instead contain a marker indicating that there is no usable password. [2]
The failure involves two meanings assigned to the same value. A single asterisk, , can be stored for an account intended not to accept a password. Under the documented error condition, musl's password hashing function can also return . If the caller treats that result as a successfully calculated hash, comparison with the account marker can incorrectly succeed.
Another part of the interaction matters: when the stored field is too short to provide suitable salt information, OpenSSH can obtain a salt from another account. Alpine identifies the presence of a local SHA-256-crypt or SHA-512-crypt password hash as a prerequisite for its documented scenario. The account supplying that hash need not be the account the attacker attempts to access. [2]
The research disclosure traces the interaction through historical error-handling and timing-countermeasure decisions. The security lesson is broader than one comparison: an error representation that cannot match a valid hash can still match a special value in an account database. An authentication boundary must distinguish successful computation from failure before deciding whether credentials match. [5]
OpenSSH's maintainers consider the underlying cause to be outside sshd, while explicitly acknowledging that it is exploitable through sshd and can be prevented there. Their workaround and Alpine's backports are the supported operational response. Administrators do not need to settle library-level responsibility before patching. [1, 2]
This article deliberately omits payloads and reproduction instructions. The mechanism and configuration requirements are sufficient to explain the risk and guide defensive review.
The Exposure Checklist
For Alpine, assess the following conditions together rather than treating the installation of an OpenSSH package as proof of exploitability. [2]
- A reachable server:
sshdis running and an untrusted party can reach its listening endpoint. This includes internally reachable services, not just public port 22. - The affected authentication path: The standard Alpine
openssh-serverpackage is built without PAM. Theopenssh-server-pamvariant is also affected when running withUsePAM no; the package name alone does not establish protection. - Password authentication remains allowed: The effective
PasswordAuthenticationsetting isyesfor the relevant connection and account. - A susceptible account exists: Alpine identifies accounts whose password field is the single
*marker, including certain key-only users. Its advisory also flags directory-service users reached through musl-nscd that lack a shadow entry. - The relevant local hash state exists: At least one local account has the
$5$or$6$hash format identified by Alpine. Account-state changes can therefore alter exposure without any change to the SSH package.
Normal access restrictions still matter. An account must be eligible for the relevant SSH access, and additional required authentication methods can change whether password authentication alone is sufficient. Review account allowlists, group policies and AuthenticationMethods rather than assuming that the CVE bypasses every independent control. [7]
Alpine explicitly excludes systems with password authentication disabled, the PAM server variant actively using UsePAM yes, and containers that do not run sshd. A web application does not become remotely exploitable through SSH merely because its container image uses Alpine. Conversely, a custom image that starts an SSH daemon needs its own assessment. [2]
The researcher also calls attention to other musl-based or configurable embedded environments. Treat those as inventory leads, not as a declaration that every OpenWrt, Buildroot or Yocto image is affected. Confirm the actual SSH implementation, libc, build options and runtime configuration. An OpenSSH finding must not automatically be applied to a different server such as Dropbear. [5]
Key-Only Accounts Are Not the Same as Key-Only SSH
Two statements that sound similar have different security consequences:
"Our administrators always use keys" describes user behavior. It says nothing about whether the daemon still offers a password authentication path.
"The server rejects password authentication for these users" describes an enforced policy. That is the relevant protection against the documented bypass.
The same distinction applies to password-field markers. In Alpine's described non-PAM configuration, * is used to prevent ordinary password matching while retaining key access. An account locked with ! is treated differently and is excluded by Alpine's advisory. Do not bulk-replace markers as an improvised fix: doing so can also disable legitimate key-based access. Use the supported update or the documented SSH configuration mitigation instead. [2]
Nor is PermitEmptyPasswords no equivalent to disabling password authentication. This vulnerability is not simply an empty-password login. A stored account marker and a password-hashing error are being confused, so an empty-password restriction addresses a different condition. [2, 7]
Root Access and the Tiny-Cloud Case
The initial impact is authentication as a susceptible account. Whether that leads to root depends on separate account and privilege policies.
Alpine notes that its base image has used a * password field for root since approximately version 3.16. OpenSSH's default PermitRootLogin prohibit-password blocks the direct root password route; changing it to yes can remove that protection. Keeping direct root password login disabled does not protect a different susceptible account that can subsequently elevate privileges. [2, 7]
The official tiny-cloud images deserve particular attention. Alpine identifies qcow2, VHD and AMI artifacts from 3.18.11 through 3.24.3 containing an alpine account with the relevant marker and passwordless doas privileges. According to the advisory, those images are safe on first boot under the described initial account state. Adding a qualifying password hash, for example through console-password provisioning, can make them exploitable. [2]
That is a configuration transition, not evidence that every fresh cloud instance is immediately compromised. It also means an earlier assessment can become stale after ordinary administration. Review provisioning, user-data and subsequent account changes, not just the original image label.
Images built from 3.21.10, 3.22.8, 3.23.8 and 3.24.4, or subsequent fixed point releases on those branches, include the patched package. Releasing a new image does not update an already running VM. Existing instances still require remediation. Alpine separately notes that cloud-init configurations which enforce PasswordAuthentication no avoid this path; cloud-init and tiny-cloud should not be treated as interchangeable labels. [2, 6]
Fixed Releases and Alpine Backports
The upstream Portable OpenSSH release containing the workaround is 10.6p2. Distribution packages may carry the same fix while retaining an older upstream version. Use the full package revision and the vendor advisory, not a simple comparison of the SSH banner with 10.6p2. [1, 2]
Alpine lists these fixed package versions:
- Alpine edge:
10.6_p2-r0. - Alpine 3.24:
10.3_p1-r2. - Alpine 3.23:
10.2_p1-r1. - Alpine 3.22:
10.0_p1-r11. - Alpine 3.21:
9.9_p2-r1. - Alpine 3.20:
9.7_p1-r6. - Alpine 3.19:
9.6_p1-r3. - Alpine 3.18:
9.3_p2-r4. - Alpine 3.17:
9.1_p1-r7. - Alpine 3.16:
9.0_p1-r6.
These are the advisory's fixed revisions, not instructions to downgrade a newer patched installation. The November 5 point releases 3.21.10, 3.22.8, 3.23.8 and 3.24.4 include the update. Alpine says it checked affected releases from 3.21 through 3.24 and edge, as well as older 3.16 through 3.20 releases. [2, 6]
Alpine 3.21 reached end of support on November 1, 2026, according to this advisory. The exceptional packages for that branch and older branches close this issue; they do not restore comprehensive ongoing support. Apply the emergency fix and retain a separate migration plan for unsupported systems. [2]
Remediation Without Losing Administrative Access
Start with the vendor's package procedure on the correct release branch, then explicitly restart the SSH daemon. Alpine warns that the package upgrade does not perform that restart for you. For containerized SSH services, rebuild from patched packages and replace the running workload; changing an image tag in a repository does not change an existing container. [2]
Before restarting or changing authentication, confirm a working administrative key and a recovery route, such as a console. Preserve the current session until a fresh authorized login has succeeded. This is especially important for remote appliances where SSH is the only routinely used management path.
If patching is temporarily blocked, Alpine documents PasswordAuthentication no followed by a daemon restart as a mitigation that closes the described SSH path. Apply it to the effective configuration for all relevant users and connection contexts. [2]
Configuration inspection needs more care than searching for one line. Included files, first-value behavior and conditional Match blocks can change the result. Alpine's default configuration reads its drop-in directory from 3.19 onward; older defaults ignore that directory. A mitigation file that is never included provides no protection. [2, 7]
Validate syntax before restarting and inspect effective settings with the daemon's configuration-test facilities. Where conditional rules are present, evaluate representative user and connection contexts. Confirm the resulting service behavior with a normal authorized login rather than running an exploit against production.
Installing the PAM variant without actually enabling a supported PAM configuration is not sufficient. A rushed authentication-stack migration can introduce lockouts or policy changes. For immediate remediation, prefer the published patched package or the explicit password-authentication mitigation.
Finally, verify the full server package revision and the restarted service on every relevant host. Updating a laptop's SSH client does not fix a remote server. Updating the host does not automatically fix a separately packaged daemon inside a container. Record those boundaries in the remediation ticket.
Detection: Look for Password Success Where None Was Expected
Alpine recommends inspecting /var/log/messages for SSH events containing Accepted password for a user that should have no working password, including relevant key-only accounts. Review the configured equivalent destination where logs are redirected or forwarded centrally. [2]
The most valuable signal is the contradiction between a successful password authentication and the account's intended state. It is not necessarily a burst of failed attempts. Controls that react only after repeated password failures may miss a successful bypass.
Investigate such an event promptly, but reconstruct the historical state before attributing the method. A user might previously have had a password, a controlled test might explain the event, or the account may have changed since the timestamp. Present-day account inventory alone cannot prove what configuration was active at login time.
Correlate the event with source addresses, session records, configuration-management history and account changes. Alpine specifically recommends reviewing doas usage, newly created users, files and authorized keys. Extend that review to unusual outbound connections and access to credentials or workloads available to the account. [2]
Do not log submitted passwords in an attempt to identify this issue. Routine authentication records should establish the account, method, source and outcome without collecting secrets. Missing logs, retention gaps or an empty search result cannot establish that an exposed machine was never accessed.
A version-only scanner also has limits in both directions. An older banner may belong to a patched distribution package, while a package finding cannot by itself establish the necessary runtime configuration. Combine vendor package status with authenticated configuration inventory. Preserve account-state evidence securely without exporting password hashes into ordinary tickets or dashboards.
When Exposure Becomes an Incident
Alpine advises treating the machine as compromised if an unauthorized login cannot be ruled out. That decision is particularly important when a susceptible account has broad privileges or when telemetry is incomplete. [2]
Preserve authentication logs, configuration history and relevant host evidence before routine cleanup. If suspicious access is supported by the evidence, isolate the affected system through the incident-response process and scope what the account could read, change or execute.
Review unauthorized keys, scheduled jobs, account changes and altered application files. Assess credentials, deployment tokens and other secrets that were actually reachable. Revoke and rotate exposed credentials from a trusted environment after containment; changing the account password alone does not remove persistence or close the vulnerable authentication path.
If privileged access occurred or system integrity cannot be established, restore or rebuild from a trusted baseline. Include machine images, provisioning scripts and reusable container layers in the recovery plan so the same vulnerable state is not deployed again.
Patching and incident closure are different milestones. A fixed daemon prevents the documented bypass on subsequent authentication attempts, but it does not automatically terminate every established session, remove an added authorized key or invalidate secrets obtained earlier.
The Takeaway
sshole demonstrates how a mature security service can fail at the boundary between account semantics and a system-library return value. No cryptographic key needs to be broken when an error is mistaken for a valid authentication result.
For operators, the response is concrete: identify OpenSSH servers on musl, verify whether PAM and password authentication are actually in use, and review susceptible account states. Install the vendor's fixed package, restart the daemon and verify the running service. Where an update must wait, explicitly disable the documented password path and validate the effective policy.
The lasting lesson is equally practical: key-based login habits are not a substitute for an enforced key-only authentication policy.
Sources
- OpenSSH 10.6p2 Release Notes - November 5, 2026; upstream workaround, affected environment and reporter credit.
- Alpine Linux: OpenSSH-Server Password Authentication Bypass - Exposure conditions, package revisions, tiny-cloud details, mitigation and investigation guidance.
- NVD: CVE-2026-123158 - CVE description and MITRE's CVSS v3.1 8.1 assessment, consulted November 6, 2026.
- CVE Program Record: CVE-2026-123158 - Published CNA record and CISA enrichment distinguishing proof-of-concept availability from confirmed active exploitation.
- sshole Research Disclosure - Özgün Kültekin of Wakefield; explanation of the library and account-marker interaction and discovery methodology.
- Alpine 3.21.10, 3.22.8, 3.23.8 and 3.24.4 Released - November 5, 2026; point releases containing the server fix.
- OpenSSH Daemon Configuration Manual - AuthenticationMethods, PasswordAuthentication, PermitRootLogin, Include and Match semantics. Use the installed platform's manual for platform-specific options.
