--- title: "SSHole: A 257-Character Password Can Log You In on Alpine Linux" author: "Anshu Pathak" published: "2026-11-06T11:25:36.805Z" updated: "2026-11-06T11:25:36.805Z" url: "https://zyvop.com/sshole-a-257-character-password-can-log-you-in-on-alpine-linux-4trgp" canonical: "https://zyvop.com/sshole-a-257-character-password-can-log-you-in-on-alpine-linux-4trgp" tags: ["alpine","openssh","linux","security","musl"] --- # SSHole: A 257-Character Password Can Log You In on Alpine Linux How a password over 256 characters unlocks password-less accounts on Alpine and other musl Linux systems, and how to fix it. ![Cover image]() On November 5, 2026, OpenSSH shipped 10.6p2 to close an authentication bypass in sshd on musl-based Linux. On an affected machine, an account that should never accept a password will accept almost any password between 257 and 1,024 bytes long. It takes one connection and works every time. The bug was reported by Özgün Kültekin of Wakefield, who wrote it up with a great timeline at [sshhole.com](). Here's the short version for developers. ## How it works Nothing here is a single mistake. Four old, reasonable decisions line up: 1. `*` **means "no password".** In `/etc/shadow`, a field that is just `*` can never match any hash. This is how key-only users and many service accounts are marked. 2. **sshd borrows a salt.** Without PAM, sshd checks a password by hashing it with `crypt()` and comparing the result to the stored field. Since the 2016 fix for a user-enumeration timing leak (CVE-2016-6210), if that field is too short to contain a salt, sshd borrows another account's salt so the check takes as long as a real one. 3. **musl's** `crypt()` **returns** `*` **on failure.** Where POSIX says to return a null pointer on error, musl returns `*`. Its `$5$` and `$6$` implementations refuse keys longer than 256 bytes (a DoS limit), so an oversized password makes `crypt()` fail, and fail with `*`. 4. **Compare** `*` **to** `*`**.** sshd sees that the "hash" it computed equals the stored field, and lets you in. ```mermaid sequenceDiagram participant A as Attacker participant S as sshd participant C as musl crypt() A->>S: Password login as a * user, 300 characters S->>C: crypt(password, borrowed salt) C-->>S: * (error, key is over 256 bytes) S-->>A: Stored * equals *, login accepted ``` ## Who is affected All of these must be true, per Alpine's advisory: - sshd runs on musl **without PAM**: Alpine's `openssh-server`, or `openssh-server-pam` with `UsePAM no` - `PasswordAuthentication` is `yes`, which is the OpenSSH default - An account's password field is exactly `*`: key-only users (created with `adduser` and no password, or `usermod -p '*'`), directory users coming through musl-nscd, root (Alpine ships `root:*`, but the default `PermitRootLogin prohibit-password` protects it), and the `alpine` user in tiny-cloud images - At least one **other** local account has a `$5$` or `$6$` hash. One is enough, and it makes every password-less account reachable Not affected: locked accounts (`!`), systems with `PasswordAuthentication no`, `openssh-server-pam` with `UsePAM yes`, containers that don't run sshd, glibc systems, and Dropbear. The cloud images deserve a closer look. Official tiny-cloud images from 3.18.11 through 3.24.3 ship the `alpine` user with passwordless `doas`. They are safe on first boot, but become exploitable as soon as any `$6$` hash exists on the machine, for example after someone sets a console password or user-data adds a user with `hashed_passwd`. From there it's a password bypass, then `doas` to root. ## What to do Update, then restart. Upgrading the package does not restart a running sshd: ```bash apk upgrade -U -a rc-service sshd restart ``` Fixed `openssh` packages exist for edge and every branch back to 3.16 (for example `10.0_p1-r11` on 3.22 and `9.9_p2-r1` on 3.21). The full table is in the advisory. If you can't update yet, turn off password logins. Keep your current session open and confirm key login works first: ```bash mkdir -p /etc/ssh/sshd_config.d echo 'PasswordAuthentication no' > /etc/ssh/sshd_config.d/00-no-passwords.conf sshd -t && rc-service sshd restart sshd -T | grep -i passwordauthentication # expect: passwordauthentication no ``` The default config reads `sshd_config.d` only from 3.19 onward, and existing `PasswordAuthentication` lines in `sshd_config`, including inside `Match` blocks, can still win. The advisory has a `sed` variant that covers those cases, and the final `sshd -T` line tells you whether it worked. Then check for signs of abuse. On Alpine, look for `Accepted password for` lines in `/var/log/messages` that name an account with no password: ```bash grep "Accepted password for" /var/log/messages ``` If you find one you can't explain, treat the host as compromised: review `doas` use, new users, changed files, and `authorized_keys`. ## The takeaway OpenSSH's release notes call 10.6p2 a workaround in sshd and say the root cause sits outside it. The advisory said no CVE had been assigned yet; CVE-2026-123158 has since been widely reported, so check NVD for the current record. The lesson goes beyond SSH: an error return should never be able to look like valid data. ## Sources - [sshhole.com]() - [Alpine Linux security advisory, 2026-11-05]() - [OpenSSH release notes, 10.6p2]()