Any password over 256 characters opened locked accounts on Alpine. A NULL license plate explains why.

On Alpine and other musl systems without PAM, any password over 256 characters opened accounts locked with an asterisk. A NULL license plate shows the same mistake.

Share
A metal padlock hanging on a blue door
Illustrative stand-in; there is no photo of a software bug. Photo by Kaffeebart on Unsplash

On 5 November 2026 OpenSSH released version 10.6p2 and Alpine Linux published an advisory for a bug that sounds like a joke: on some systems, any password longer than 256 characters logs you in to accounts that are not supposed to accept a password at all. It needs four things together: OpenSSH built against the musl C library without PAM (Alpine's openssh-server package), password logins left on (the default), an account whose password field is *, such as root or a key-only user, and one other local account with a real SHA-256 or SHA-512 password hash. The fix is OpenSSH 10.6p2 or Alpine's patched packages, then a restart of sshd, or PasswordAuthentication no. The cause is two meanings sharing one character.

257+characters, any characters, opened a * account
256byte limit on musl's SHA-crypt passwords
2012year musl began returning * on error
17,600test logins in the researcher's check

Sources: Alpine Linux advisory, 5 Nov 2026; sshhole.com.

How can a long password open a locked account?

In the shadow password file, a * means no password will ever match, because it is not a valid hash. Without PAM, sshd checks a password itself: it runs what you typed through the C library's crypt() with the stored salt and compares the result with the stored field. A * has no salt in it, so sshd borrows one from another account on the machine. According to the researcher's write-up, that borrowing goes back to a 2016 OpenSSH change made to stop attackers from telling real usernames from fake ones by timing.

Guess first: how long, and what, does a password need to be to open a locked root account on an affected Alpine host?

Any 257 characters or more. What they are doesn't matter. The account only needs * in its password field, and the machine needs one other account with a real SHA-256 or SHA-512 hash. Source: Alpine Linux, sshhole.

Then musl's crypt() hits a limit. musl caps SHA-crypt passwords at 256 bytes, a guard against denial of service, and fails on anything longer. Its failure value, in the words of its own source comment as quoted on sshhole: "on error "*" is returned." So sshd hashes your 300-character password, gets back *, compares it with the stored *, and they match. The door's "locked" sign and the library's "something went wrong" sign are the same character.

Who got it wrong?

My first reaction was that musl broke the rules. The POSIX specification for crypt() says that on failure "it shall return a null pointer and set errno". musl chose in 2012 to return a string instead. But that was a safety choice, not carelessness: a program that forgets to check for a null pointer can crash or worse, and a string that can't match any hash looked safer. sshhole notes that a 2013 Debian bug asked glibc to do the same. It was closed after the move to libxcrypt, which returns *0.

How the pieces lined up
  1. 1980 BSD puts * in the password file for the daemon account
  2. 1997 The Single UNIX Specification says crypt() returns a null pointer on failure
  3. Aug 2012 musl returns * or x instead, and adds a 256-byte limit for SHA-crypt
  4. Jul 2016 OpenSSH borrows real salts for invalid users, to stop timing-based user enumeration
  5. 2022 Alpine 3.16 changes root's field from ! to * so key logins work without PAM
  6. 5 Nov 2026 OpenSSH 10.6p2 and Alpine's advisory close the bypass

Sources: sshhole.com timeline; OpenSSH 10.6p2 notes.

Then look at the other pieces. OpenSSH's salt borrowing was a fix for a real enumeration bug. Alpine changed root's password field from ! to * in 2022 so that key logins kept working without PAM, with a commit message saying it "still forbids password login". The OpenSSH maintainers wrote in the 10.6p2 release notes that they consider "the root cause of this bug to be outside sshd". Every step was reasonable on its own. The bug lives in the space between them, which is why the researcher's test of about 17,600 logins across builds found that "every build agreed on every login. except musl without pam."

What does a license plate have to do with it?

In late 2016 a security researcher named Joseph Tartaro picked a vanity plate in California: NULL. At DEF CON in 2019 he explained what followed, as The Drive reported. A privately run citation processing centre kept tickets with missing plate details under "NULL". Its system could not tell those apart from his plate, so it sent them to him, more than $12,000 worth. "Instead, I got all the tickets," he told the audience.

A California license plate on the back of a car
Illustrative, not the NULL plate. Photo by Ed Parker on Unsplash

The shape is identical. A system needed a way to say "nothing here" and wrote it in the same alphabet as real values.

As long as no real value equalled the marker, nothing happened. The moment one did, whoever held it received everything addressed to nothing.

On the plate it was a person. In sshd it was any attacker who could type 257 characters.

Two systems, one mistake

The NULL plate (California, 2016 to 2019)

  • "Nothing here" marker NULL, for tickets with no plate recorded
  • Real value equal to it one driver's vanity plate
  • Who got everything the plate's owner, over $12,000 in tickets
  • Repair the processing centre cancelled the debt

sshd on musl (2026)

  • "Something failed" marker *, from musl's crypt()
  • Real value equal to it the * that locks root and key-only users
  • Who got everything anyone typing 257 characters
  • Repair OpenSSH 10.6p2 avoids the comparison

Sources: The Drive, 13 Aug 2019; Alpine Linux; OpenSSH.

Card: the asterisk in /etc/shadow means no password can match; musl crypt() returns an asterisk as its error for passwords over 256 bytes; sshd compares the two, they are equal, and the login is accepted
Card by Daily Ferment. Sources: Alpine Linux advisory and OpenSSH 10.6p2 notes, 5 Nov 2026; sshhole.com.

That is also why I'm wary of calling libxcrypt's *0 the fix. It is safer today because no stored field is *0. It is still a value. The only marker that can't collide is one that lives outside the data, which is what POSIX's null pointer was trying to be. It reminds me of the certificate keys that could be guessed in 256 tries: a small assumption nobody wrote down, sitting between components that each passed their own review.

What should you do now?

Update OpenSSH with apk upgrade -U -a and restart sshd, because the upgrade does not restart a running daemon. If you can't update yet, set PasswordAuthentication no after confirming key login works. Alpine says official tiny-cloud images from 3.18.11 through 3.24.3 ship an alpine user with a * password and passwordless doas, so those need checking instance by instance. And look in /var/log/messages for "Accepted password for" on accounts that have no password. Alpine's advice is to treat the machine as compromised if you can't rule a login out. Nobody knows yet whether this was used before 5 November. The researcher's own line is "as far as anyone knows, nobody noticed."

If this is your stack, the PHP end-of-life piece asks a related question: who carries the fix for the versions nobody maintains.

Established
The conditions, cause and fixes in Alpine's advisory and the OpenSSH 10.6p2 notes. The musl, POSIX and Alpine history as published on sshhole and the POSIX page. The NULL plate story as reported in 2019.
Inferred
That each step was reasonable on its own and the bug lives between them. That the NULL plate is the same failure: a marker written in the data's own alphabet. That *0 is safer only as long as nothing stores *0.
Still a guess
That other in-band error markers like this are waiting in other libraries, found only when two of them meet. Whether anyone used this one before 5 November is unknown.
The claim, in one sentence

An error marker written in the same alphabet as real data will one day equal some real data, and whoever holds that value gets everything addressed to nothing.

More on Daily Ferment: NIST's curve seeds were timestamps. No record said so. and The HFS bug was public for 11 weeks. The write-up got it exploited in a day.

Sources