OpenSSH Emergency Fix: The Alpine Linux Login Bypass Explained, With a Worked Example

OpenSSH Emergency Fix: The Alpine Linux Login Bypass Explained, With a Worked Example

How a harmless-looking asterisk could let an attacker log in, how to tell whether you are exposed, and how to fix it safely

Imagine a server account that has no password. Now imagine that an attacker can log in to it anyway, because a password check mistook an error message for a correct answer. That is the bug at the centre of this week's OpenSSH emergency release.

Today is November 6, 2026, and this matters right now because Portable OpenSSH 10.6p2 came out only yesterday, on 5 November, with an urgent request from the project. If you run musl-based Linux servers with password authentication switched on, the developers want you to disable password logins or disable SSH immediately until you can act.

Many teams will read that headline and either panic or shrug. Both are mistakes. Most Linux servers are not affected, but the servers that are affected may include ones you have always called "key-only". This guide explains the bug in plain language, shows exactly how to check a server, and walks through a full example from discovery to verified fix.

What happened, in plain words

SSH is the tool administrators use to log in to servers remotely. OpenSSH is the most widely used version of it.

Every Linux program relies on a C library, a shared collection of basic functions. Most Linux systems use one called glibc. Alpine Linux uses a smaller one called musl, which is a big part of why Alpine is so popular for containers and small cloud servers.

The bug lives in the meeting point between those two pieces of software. OpenSSH's developers consider the underlying cause to sit outside OpenSSH, but they also recognise that the SSH server provides the path to exploit it and a practical place to block it. So 10.6p2 adds a workaround. The flaw was found by Özgün Kültekin of Wakefield.

How an error turns into a successful login

Here is the logic, step by step, with no exploit detail.

When a server checks a password without PAM (Pluggable Authentication Modules, a common system for handling logins), it does something simple. It hashes the password the visitor typed, then compares the result with the value stored for that account.

A hash needs a salt, which is a small random value mixed in so that identical passwords produce different results. If the stored value for an account is too short to supply a salt, OpenSSH can borrow one from another account on the same machine. It does this for a good reason: since 2016 it has tried to stop attackers from guessing which usernames exist, a response to the flaw CVE-2016-6210.

Now the collision. When musl's crypt() function is given a password that is too long for certain hash types, it refuses and returns the single character * to signal an error.

But * is also what many systems store in the password field of an account that is not meant to have a password.

So the server compares two values:

  • What it calculated: *, which really means "error".
  • What it has stored: *, which really means "no usable password".

They match. The login succeeds.

Think of a bouncer checking names against a list. The scanner breaks and prints "ERROR". One entry on the list, added as a note for staff, also says "ERROR". The bouncer sees two identical words and waves the person in. Nobody lied, and each part did its job. The danger came from one value meaning two different things.

The researcher traces the interaction to musl changes in 2012 and that 2016 OpenSSH change. He reports finding it through about 17,600 test logins across build and login combinations, with help from AI agents.

Are you affected? The four conditions

The Alpine advisory lists four conditions, and all of them matter:

  1. OpenSSH checks passwords without PAM.
  2. PasswordAuthentication is enabled.
  3. The target account's password field contains *.
  4. Another local account has a password hash beginning with $5$ or $6$.

Alpine's standard openssh-server package does not use PAM. Installing openssh-server-pam does not settle it either, because you are still exposed if UsePAM no is set.

These are outside the stated scope:

  • Non-Linux platforms.
  • Linux systems using glibc.
  • Linux systems that check passwords through PAM.
  • Containers with no running SSH server.
  • Systems with password authentication disabled.
  • Accounts locked with ! rather than *.

That last group is why "we use Alpine" is not the same as "we are vulnerable". Most Alpine containers run no SSH server at all. Equally, "OpenSSH is installed" tells you very little. You need to know the C library, the package, the running configuration and the account data.

The dangerous case: official cloud images

Alpine calls out one scenario in particular. Its official tiny-cloud images, from versions 3.18.11 through 3.24.3, include an alpine account with a * password field and passwordless doas rights. doas is a small tool, similar to sudo, that lets a user run commands as root.

Those images start out safe, because the fourth condition is missing. There is no qualifying password hash on the machine.

Then someone adds a user with a normal password, perhaps for console access. That single routine change can complete the set. An attacker could enter as alpine and become root.

The default PermitRootLogin prohibit-password setting does not help here. It stops direct password logins to root, but this route reaches root indirectly.

A worked example: Acme's jump host

Let us follow a fictional company. Acme runs a small Alpine server, bastion.example.com, that staff connect through to reach internal systems. Everyone says it is key-only. A new engineer, Rohit, has been asked to prove it.

Step 1: Confirm the platform

Rohit logs in and checks the system:

cat /etc/alpine-release
ldd --version
apk info -e openssh-server openssh-server-pam

The first command shows the Alpine version. The second names musl. The third lists which of the two packages are installed. On Acme's server, only openssh-server appears, so there is no PAM.

If ldd --version names glibc instead, or the machine runs no SSH server, they can stop and move to the next system.

Step 2: Read what sshd actually enforces

This is the step teams skip. Do not read the config file and assume. Ask the server for its effective settings:

sshd -T | grep -iE '^(passwordauthentication|usepam|permitrootlogin|authenticationmethods)'

Rohit sees this:

permitrootlogin prohibit-password
passwordauthentication yes
authenticationmethods any

There is the surprise. Password logins are on. Staff always used keys, so nobody noticed. A build without PAM may not print usepam at all, which is why this output has no such line.

Settings can also change per connection through Match rules, so they test the view for a specific user and address:

sshd -T -C user=deploy,host=bastion.example.com,addr=203.0.113.10 | grep -i '^passwordauthentication'

Step 3: Check the account data

Run as root, these two commands print account names only, never hashes:

awk -F: '$2 == "*" {print "star: " $1}' /etc/shadow
awk -F: '$2 ~ /^\$[56]\$/ {print "hash: " $1}' /etc/shadow

Rohit's result:

star: deploy
hash: backup-admin

So deploy, the "key-only" account, has a * field. And backup-admin, created last year for console access, has a qualifying hash. All four conditions are met. This server is exposed.

Step 4: Close the door first, then patch

Rohit keeps their current session open and confirms that their key works from a second terminal. A mistake here can lock everyone out, and the open session is their safety rope.

They add the setting to /etc/ssh/sshd_config:

PasswordAuthentication no

One trap: OpenSSH uses the first value it reads for most settings. If the file has an Include line near the top, or a Match block further down, the new line may not be what wins. That is why the check comes straight after the edit:

sshd -t
sshd -T | grep -i '^passwordauthentication'

sshd -t tests the configuration for errors. If it passes, they apply the published Alpine fix. Alpine has released 3.21.10, 3.22.8, 3.23.8 and 3.24.4, and the remediation on OpenRC systems is:

apk upgrade -U -a
rc-service sshd restart

The restart is not optional. Installing a package does not replace the SSH server that is already running in memory.

Step 5: Prove it from the outside

Now Rohit tests the way an outsider would, from another machine, against their own server:

ssh -o PubkeyAuthentication=no -o PreferredAuthentications=password [email protected]

The answer they want is a refusal such as Permission denied (publickey). It means the server no longer offers passwords at all. They then open a normal key-based session in a new terminal to confirm that staff can still get in.

Step 6: Look for past abuse

Patching closes the door, but it says nothing about who already walked through it. Alpine recommends reviewing logs for this exact entry:

grep 'Accepted password for' /var/log/messages

On a server where staff only use keys, a successful password login is the signal to chase. Monitoring that watches for repeated failures can miss this completely, because here the attacker's attempt looks like a success.

Rohit finds none. If they had found one for deploy, the job would have changed from patching to incident response. Alpine advises checking for privilege escalation, new users, new files and changed authorised keys, and treating the host as compromised if unauthorised login cannot be ruled out. Anything the account could reach, including stored credentials and deployment secrets, would need review and replacement.

Check how the account looked at the time of any suspicious login, too. Its current state may reflect a later change.

Step 7: Fix the factory, not just the product

Acme builds servers from a saved image. If Rohit stopped at Step 6, the next rebuild or autoscaling event could bring the old settings straight back. They update the template, set PasswordAuthentication no there, and ask why backup-admin needs a password at all.

How to read scanner results

Expect noisy reports this week. Keep two ideas separate.

The upstream version string and a distribution's patch status are different evidence. A vendor may backport a fix without changing the headline version, so follow your distribution's package guidance. If you compile OpenSSH yourself, use the 10.6p2 release notes.

Track four separate facts per server: vulnerable package identified, replacement installed, service restarted, configuration verified. "Patched" in a ticket often means only the second one.

Why the fix arrived so fast

Damien Miller said the OpenSSH team learned of the issue the day before releasing the workaround. He pointed to recent cases of AI agents independently rediscovering vulnerabilities within hours, arguing that long embargoes can favour attackers.

The release notes also describe a move toward more frequent fixes instead of holding changes for scheduled releases, while stressing that many AI-generated reports show no realistic security impact and that human analysis still matters.

For most of us, the practical result is simple. Critical fixes may now land outside your normal maintenance window. Follow vendor announcements directly, and decide in advance who is allowed to make an emergency change.

These points describe the exposure and the sensible response. They are not evidence of a confirmed attack campaign.

The real lesson: three phrases that are not the same

"Uses SSH keys", "has no password set" and "cannot authenticate with a password" sound alike, but they describe different things. The first is a habit. The second is a state of the data. Only the third is an enforced control, and you can only know it by testing the running server.

Conclusion

This is a narrow bug with a sharp edge. Most Linux systems are outside it, but a musl-based server that matches all four conditions can accept a login for an account that was never meant to have a password. Update, restart, set PasswordAuthentication no, verify from outside, read your logs and fix your templates. Then write down what "key-only" means in your organisation, and test it.

Merits

  • The exposure is specific, so teams can rule out most systems quickly.
  • Fixed Alpine releases and a simple temporary mitigation are already available.
  • The checks use standard tools and take only minutes per server.
  • Reviewing logins and account data improves security well beyond this one bug.

Demerits

  • Asset lists that only show "OpenSSH installed" cannot answer the question.
  • A routine change, such as adding a password user, can make a safe machine exposed.
  • Mistakes in SSH settings can lock administrators out.
  • Patching does not reveal or undo any earlier unauthorised access.

Caution

This article is educational and is based on published advisories and reporting available at the time of writing. Acme, Rohit, deploy, backup-admin, the hostname and the IP address are fictional placeholders, so replace them with your own values. Keep an active session open when changing SSH settings, test only systems you are authorised to test, and verify the details against the current OpenSSH and Alpine advisories, or your own vendor's guidance, before relying on them.

Frequently asked questions

  • What is OpenSSH 10.6p2? — It is an emergency Portable OpenSSH release from 5 November 2026 with a workaround for a login bypass that affects certain musl-based Linux systems.
  • Is every Alpine Linux system vulnerable? — No. A system needs a running SSH server that checks passwords without PAM, password authentication enabled, a target account with a * password field, and another local account with a $5$ or $6$ hash.
  • Are Ubuntu, Debian and other glibc systems affected? — Linux systems using glibc are outside the stated scope, as are non-Linux platforms and Linux systems that check passwords through PAM.
  • Are Alpine Docker containers at risk? — Containers with no running SSH server are outside this attack path, so the question is whether a container actually runs sshd.
  • Does PermitRootLogin prohibit-password protect me? — It blocks direct password logins to root, but it does not stop an attacker entering through another account and escalating, as in the tiny-cloud alpine account scenario.
  • Is updating the package enough? — No. You must also restart the SSH service, because the old server keeps running in memory until you do.
  • What should I do if I cannot update today? — Set PasswordAuthentication no, confirm the effective setting with sshd -T, and test key access while keeping an existing session open.
  • How do I check whether someone already used this? — Search /var/log/messages for Accepted password for entries on accounts that should not use passwords, and treat the host as compromised if unauthorised login cannot be ruled out.

Tags

#OpenSSH #AlpineLinux #LinuxSecurity #SSH #AuthenticationBypass #Musl #DevSecOps #CloudSecurity #PatchManagement #IncidentResponse

Free field guide

Incident Response: First Hour

A calm, evidence-preserving checklist for establishing control, bounding impact, communicating clearly, and containing an incident safely.