Checking Your Servers for CVE-2026-123158 (the Alpine/musl SSH Password Bypass)

Checking Your Servers for CVE-2026-123158 (the Alpine/musl SSH Password Bypass)

3 min read

On November 5, 2026, OpenSSH shipped 10.6p2 to fix CVE-2026-123158, nicknamed "sshole": a password authentication bypass in sshd on Linux systems built on musl libc without PAM. Alpine Linux is the best-known example. Here is how to find out whether you are exposed, split into two parts: the SSH configuration on your host, and the container exposure that is easy to overlook. NOT OK!

What the bug is, and what it isn't

When sshd is built without PAM on musl, an error value from the password-hashing call can be mistaken for the stored value of an account that has no password. In practice, an overly long password (roughly 257 to 1024 bytes) can log in to a password-less account. It is a logic bug, not memory corruption.

It is not a problem for glibc-based distributions such as Ubuntu, Debian, Fedora or RHEL, and it only matters where an SSH server is actually running. A container based on Alpine is not vulnerable unless it runs sshd.

The principle that matters more than this CVE: key-only access

Whatever distribution you run, and whether or not this particular bug applies to you, the best practice is the same: SSH should accept public-key authentication only, with root login disabled. Password authentication is the attack surface that bugs like this one (and years of brute-force traffic) target. If passwords are switched off, there is no password path to bypass, which is exactly why PasswordAuthentication no is the official workaround here.

Treat key-only access as the baseline for every server you operate, then use the checks below to verify it and to catch the places it can silently be undone.

Part A: Verify the host's SSH configuration

A1. Check the effective configuration

Don't trust the config file alone. Ask sshd what is actually in effect:

sudo sshd -T | grep -Ei 'passwordauthentication|permitrootlogin|pubkeyauthentication|kbdinteractiveauthentication|authenticationmethods|usepam'

For key-only access you want:

  • passwordauthentication no
  • kbdinteractiveauthentication no
  • permitrootlogin no (or prohibit-password)
  • pubkeyauthentication yes

On Ubuntu and Debian, files in /etc/ssh/sshd_config.d/ can override the main file, and cloud images often ship one that turns password authentication back on. Check them too:

sudo grep -Ri 'PasswordAuthentication\|PermitRootLogin' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/

A2. Confirm what is listening, and reload after changes

sudo ss -tlnp | grep sshd
sudo systemctl is-active ssh sshd

A config change does not take effect until the daemon reloads: sudo systemctl reload ssh.

A3. Test from outside

From another machine, try to force password authentication:

ssh -p <port> -o PreferredAuthentications=password,keyboard-interactive -o PubkeyAuthentication=no user@<server-ip>

You want Permission denied (publickey) with no password prompt. If you also have an IPv6 address, test that one as well.

A4. Check your OpenSSH version

ssh -V
apt changelog openssh-server | grep -i 'CVE-' | head -20

Distributions backport fixes without changing the upstream version number, so compare against your distro's security tracker rather than the version string alone. Key-only access does not protect you from unauthenticated bugs in sshd itself, so keep OpenSSH patched too.

Part B: Container exposure

Your host may be glibc-based and unaffected while some of your containers are built on Alpine. The question for each container is simple: is an SSH server running in it, and is it reachable?

B1. Is any container publishing port 22?

docker ps --format '{{.Names}}  {{.Ports}}' | grep -E '(:|^|->)22(/|->)'

B2. Which containers are Alpine-based, and do any have an SSH server installed?

for c in $(docker ps --format '{{.Names}}'); do
  printf '%s: ' "$c"
  docker exec "$c" sh -c '. /etc/os-release 2>/dev/null && echo "$PRETTY_NAME"' 2>/dev/null || echo "unknown (no shell)"
done

# for each Alpine container:
docker exec <container> sh -c 'apk info -e openssh-server openssh 2>/dev/null || echo none'

Minimal images with no shell won't answer; docker cp <container>:/etc/os-release - works for those. If nothing publishes port 22 and every Alpine container prints none, you are not exposed.

B3. Scan your images for the CVE

Trivy can check every running image for a specific CVE ID without installing anything on the host:

for i in $(docker ps --format '{{.Image}}' | sort -u); do
  echo "== $i"
  docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy image -q --scanners vuln "$i" | grep -i 'CVE-2026-123158'
done

If you are affected

  • Alpine hosts or containers running sshd: upgrade the package (apk upgrade -U -a) and restart sshd. The package upgrade alone does not replace the running daemon. Alpine published fixes on November 5 for all supported branches (point releases 3.21.10, 3.22.8, 3.23.8 and 3.24.4, among others).
  • Can't patch right now: set PasswordAuthentication no and restart sshd.
  • Docker images: pull current tags and recreate the containers. Running apk upgrade inside a container won't survive a recreate.

The bigger lesson

Make key-only SSH with root login disabled your default on every machine, patch OpenSSH promptly, and check what is actually running inside your containers instead of assuming. A CVE like this one is mostly a prompt to verify all three.