Bypassing Locked Accounts with a 257-Byte Password: The Alpine OpenSSH Flaw

Bypassing Locked Accounts with a 257-Byte Password: The Alpine OpenSSH Flaw

CybersecurityOpenSSHLinuxSystem Architecture

Sources:Alpine Linux + OpenSSH + Lobsters

Under traditional security principles, an account locked by the operating system cannot be accessed under any circumstances. Submitting any password should result in an immediate rejection. On November 5, 2026, a security advisory published by the lightweight operating system Alpine Linux completely shattered this common assumption.

An attacker simply needs to supply a password exceeding 256 bytes, and a locked administrator account swings wide open. The entire sequence involves no memory corruption and no hash brute-forcing. After comparing the input password with the lock indicator, the defense mechanism voluntarily grants entry.

This anomalous bypass stems from an unintended collision between three independent security controls. When an error signal indicating “calculation failure” and an account state signifying “login prohibited” happen to share the exact same character, authentication logic collapses at their intersection.

Three Defenses Align: How a 257-Byte Password Slipped Through

In the Unix shadow file /etc/shadow, an asterisk * has denoted locked accounts for decades. Whenever the password field contains a single asterisk, the system treats password authentication as disabled. A hash calculated from a valid password spans dozens of characters, making a collision with a single asterisk virtually impossible.

To prevent timing attacks that enumerate valid usernames, OpenSSH developers introduced a timing mitigation mechanism. If an account has no valid password, the daemon does not return immediately. Instead, it borrows the salt from another legitimate account on the system and performs a fake hash computation of comparable duration. As a result, server response times remain uniform whether an account exists or not.

Meanwhile, the lightweight musl C library establishes its own defensive boundaries. To prevent malicious input from exhausting memory, musl’s crypt() implementation enforces a strict length ceiling. When an input password exceeds 256 bytes, the function immediately halts calculation and returns a pointer to a static asterisk * as an error indicator.

Individually, each of these three mechanisms follows solid defensive philosophy. Yet when combined within a single system, they quietly assembled an open attack vector.

An attacker only needed to meet four prerequisites:

  1. Reach the target host’s SSH port;
  2. Find an account whose shadow password field is *, such as the default root account in Alpine since version 3.16;
  3. Have at least one other legitimate account configured with a $5$ (SHA-256) or $6$ (SHA-512) password hash;
  4. Submit an oversized password between 257 and 1024 bytes in length.

When all four conditions are met, OpenSSH takes the oversized password and calculates a fake hash using the borrowed salt. The underlying musl library aborts due to the length limit and returns the error sentinel *. OpenSSH then compares this return value with the password field in the shadow file—both evaluate to a single asterisk. The check succeeds, and the locked door opens.

Alpine Official Security Advisory Screenshot Figure: Alpine Linux official security advisory disclosing the authentication bypass without PAM. Source: alpinelinux.org.

One Asterisk, Two Meanings: Account Lock Meets Error Sentinel

The core issue behind this flaw lies in conflicting semantics assigned to the same character across different software layers. Upper-layer software treats the asterisk as an unpickable lock, while the underlying C library treats it as a white flag signaling an error.

In traditional Unix implementations, cryptographic functions usually return a null pointer upon invalid input. Callers simply verify whether the pointer is null to differentiate success from failure. However, null pointers frequently caused null dereference crashes in legacy software. musl adhered to a specification that returns a pointer to a static string * on error instead.

This design assumes callers recognize an asterisk as an invalid hash. Under normal circumstances, this holds true. Even if a submitted password returns an asterisk, genuine accounts hold full password hashes, preventing any match.

OpenSSH’s fake salt logic introduced the fatal twist. In minimal environments without PAM, the daemon validates passwords directly. To keep attackers from guessing account validity through response timing, OpenSSH computes a hash even for locked accounts.

This trapped the authentication flow in an unhandled edge case. OpenSSH presumed it was verifying a candidate password, while the underlying library had actually aborted. A subtle divergence in API contracts turned a static lock into a master key.

Cloud Images with Pre-Configured Accounts: Adding One User Sparks the Risk

Following the disclosure, the security community rapidly evaluated real-world exposure. Not all Alpine deployments are vulnerable; actual risk hinges on specific system configuration.

Lightweight containers running standalone microservices typically do not expose SSH, naturally closing the attack path. Hosts with password authentication disabled (PasswordAuthentication no) are equally immune. Systems utilizing PAM authentication handle credential verification through dedicated modules, avoiding this direct string comparison altogether.

The true trap lies in cloud templates. Alpine’s official tiny-cloud images between versions 3.18.11 and 3.24.3 pre-provisioned a default alpine user. In /etc/shadow, this user’s password field was set to *, accompanied by passwordless sudo privileges.

On a freshly deployed instance, this account remains safe. Because no other user exists with a salted hash, OpenSSH cannot borrow a salt and never triggers the fake computation logic. Many operators mistakenly assumed the default image was entirely immune.

The vulnerability detonates the moment an administrator provisions the first regular user. Once a standard account with a password hash is added to /etc/shadow, the dormant alpine account turns into an unauthenticated backdoor. An attacker supplying a 257-byte password can log into the account and escalate to root instantly.

Upgrades Require Daemon Restarts: Mitigating via Configuration

No specific CVE identifier was assigned when the advisory was published. Security researcher Özgün Kültekin initially discovered the vulnerability, leading to coordinated patches by the OpenSSH and Alpine teams. The fix was documented in OpenSSH 10.6p2 release notes, covering Alpine branches from 3.16 to 3.24 as well as edge.

Impacted systems should synchronize package repositories and update immediately. Running apk upgrade -U -a replaces OpenSSH with the patched version, which explicitly rejects abnormal return characters from underlying libraries, eliminating symbol ambiguity.

OpenSSH Official Release Notes Screenshot Figure: OpenSSH 10.6p2 release notes detailing fixes for oversized passwords and fake salt matching. Source: openssh.com.

Crucially, replacing binaries on disk does not mitigate risk for running processes. The old daemon remains active in memory, leaving the host vulnerable. Administrators must execute rc-service sshd restart immediately after updating packages to load the patched binary.

For production hosts where restarts cannot be scheduled right away, password authentication can be disabled as an emergency mitigation. Administrators can place PasswordAuthentication no into /etc/ssh/sshd_config.d/00-no-passwords.conf, test the configuration, reload the service, and verify the setting via sshd -T. When auditing access logs, successful login records for passwordless accounts in /var/log/messages indicate potential prior compromise.

Software security frequently breaks down at system boundaries. When individual components adhere to defensive best practices but interpret interface contracts with minor semantic differences, carefully designed perimeters unravel from within. Preserving clear, unambiguous symbol semantics remains an engineering imperative far more fundamental than layering defensive checks.

References:

  • Alpine Linux Security Advisory
  • OpenSSH 10.6p2 Release Notes
  • Lobsters Community Discussion