---
title: 'Alpine Linux Security Advisory: OpenSSH-server password authentication bypass'
link: https://alpinelinux.org/posts/2026-11-05-openssh-password-authentication-bypass/
source: hnrss-org
published: 2026-11-05T14:44:20Z
updated: 2026-11-05T14:44:20Z
first_seen: 2026-11-05T17:57:26.867095589Z
authors:
- pantalaimon
content: extracted
html: 2026-11-05-alpine-linux-security-advisory-openssh-server-password.html
remote_preview:
  url: https://alpinelinux.org/alpinelinux-logo.svg
---

**If you run `sshd` on Alpine Linux, update `openssh` now and restart `sshd`.** Upgrading the package alone does not replace the running daemon.

If you cannot update yet, at least disable password logins: set `PasswordAuthentication no` in your sshd configuration and restart `sshd`. Either one closes the hole.

## What is the problem?

An attacker who can reach your SSH port can log in without knowing any password. It takes one connection, works every time, and needs no retries.

The attacker needs the name of an account whose password field is `*` (an account with no password set, which is normal for key-only accounts), and needs the machine to have at least one other account with a `$5$` or `$6$` password hash. The attacker then sends a very long password (257 to 1024 bytes). One user with a password is enough: it makes every account without one reachable.

Details are in the [OpenSSH 10.6p2 release notes](https://www.openssh.com/releasenotes.html). No CVE identifier had been assigned at the time of writing.

## Who is affected?

You are affected if all of the following are true:

- You run the Alpine `openssh-server` package, which is built without PAM, or you run `openssh-server-pam` with `UsePAM no`. (`openssh-server-pam` with `UsePAM yes` is not affected.)
- `PasswordAuthentication` is `yes` (the OpenSSH default, unless you changed it).
- The machine has an account whose password field is `*`. This includes:
  - `root`, which ships as `root:*` in the base image since about Alpine 3.16. OpenSSH’s default `PermitRootLogin prohibit-password` protects root, so root is only reachable if `PermitRootLogin yes` is set. That does not help if another account that can log in is able to become root, for example through `doas`.
  - Any key-only user created with `adduser` without a password, or with `usermod -p '*'`.
  - Users coming from a directory service through musl-nscd (nslcd, winbind, sssd), since they have no shadow entry.
  - The `alpine` user in the official **tiny-cloud** images (see below).
- At least one local account has a `$5$` or `$6$` password hash.

Affected releases: every Alpine release we checked, 3.21 through 3.24 and edge, and the older releases that no longer receive regular updates (3.16 to 3.20).

### Who is not affected?

- **Docker and other container users** that do not run `sshd` in the container.
- Systems with `PasswordAuthentication no`.
- Systems using `openssh-server-pam` with `UsePAM yes` (with `UsePAM no` you are affected).
- Locked accounts: those with `!` as the password field in `/etc/shadow` (a line starting `user:!:`). They cannot log in with a password or a key.
- Systems where no account has a `$`-style password hash.
- Cloud images configured through cloud-init, which writes `PasswordAuthentication no`.

## How can I fix it?

### 1\. Update

```
apk upgrade -U -a
```

Alpine 3.21.10, 3.22.8, 3.23.8 and 3.24.4 contain the fixed package (see the [release announcement](https://alpinelinux.org/posts/alpine-3.21.10-3.22.8-3.23.8-3.24.4-released/)). The fixed package versions are:

| Branch | Fixed `openssh` version |
| ------ | ----------------------- |
| edge   | 10.6\_p2-r0             |
| 3.24   | 10.3\_p1-r2             |
| 3.23   | 10.2\_p1-r1             |
| 3.22   | 10.0\_p1-r11            |
| 3.21   | 9.9\_p2-r1              |
| 3.20   | 9.7\_p1-r6              |
| 3.19   | 9.6\_p1-r3              |
| 3.18   | 9.3\_p2-r4              |
| 3.17   | 9.1\_p1-r7              |
| 3.16   | 9.0\_p1-r6              |

**Restart `sshd` after upgrading** (`rc-service sshd restart`). Upgrading the package does not restart a running `sshd`, so you must do it after.

### 2\. If you cannot update: disable password authentication

Before you start, make sure your SSH key login works, and keep your current session open until you have tested a new login.

Run these as root. The first two commands create a drop-in file. Alpine’s default `sshd_config` reads that directory from 3.19 onward; older releases ignore it. The `sed` command changes `yes` to `no` on every `PasswordAuthentication` line in `/etc/ssh/sshd_config`, whatever the spacing, including lines inside a `Match` block. It also adds `PasswordAuthentication no` at the top of the file, for the case where there was no such line, and saves the original as `/etc/ssh/sshd_config.bak`. The last two commands check the configuration, restart the daemon, and show the result:

```
mkdir -p /etc/ssh/sshd_config.d
echo 'PasswordAuthentication no' > /etc/ssh/sshd_config.d/00-no-passwords.conf
sed -i.bak -e '1i PasswordAuthentication no' \
  -e 's/^\(\s*PasswordAuthentication[^y#]*\)yes/\1no/i' \
  /etc/ssh/sshd_config
sshd -t && rc-service sshd restart
sshd -T | grep -i passwordauthentication
```

The last command should print `passwordauthentication no`. To undo, delete `/etc/ssh/sshd_config.d/00-no-passwords.conf` and copy `/etc/ssh/sshd_config.bak` back over `/etc/ssh/sshd_config`.

## Cloud images (tiny-cloud)

The official tiny-cloud images (the qcow2, VHD and AMI artifacts) from **3.18.11 through 3.24.3** ship an `alpine` user with a `*` password field and passwordless `doas`. They are safe on first boot. They become exploitable as soon as any `$6$` hash exists on the machine, for example when an admin sets a console password, or user-data adds a user with `hashed_passwd`. An attacker then gets a shell as `alpine` and can use `doas` to become root.

Images built from 3.21.10, 3.22.8, 3.23.8, 3.24.4 and later include the fixed package. Images from earlier point releases do not, so on every running instance, update `openssh` or disable password authentication.

## Releases that are no longer supported (3.21 and older)

These releases have the same bug. 3.21 reached its end of support on 2026-11-01, but we have published fixed packages for each release all the way back to 3.16.

## How do I know if I was attacked?

Look in `/var/log/messages` for `sshd` lines reading `Accepted password for` an account that has no password (`alpine`, `root`, or any key-only user). Review `doas` use and recently created users, files and authorized keys on exposed machines. If you cannot rule out a login, treat the machine as compromised.

## How could this happen?

When sshd is built without PAM, it checks a password by hashing the attempt with `crypt()` (the C library function that turns a password into its stored hash) and comparing the result to the stored password field. For an account whose stored field is too short to contain a salt (the random prefix of a hash), sshd borrows the salt of another account.

musl’s `crypt()` returns the string `*` as an error indicator when the key is over 256 bytes long. `*` is also exactly what the stored field contains for every account with no password, so the “hash” matches and the login succeeds.

OpenSSH 10.6p2 avoids the problem in sshd. The stable-branch packages above carry a patch for the same problem.

## Credits

Reported by Özgün Kültekin of [Wakefield](https://wakefield.co). Thanks to Damien Miller and Darren Tucker of the OpenSSH project for the fix and the 10.6p2 release, to Timo Teräs for help analyzing the issue, and to Natanael Copa, who built and uploaded the updated packages.
