← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2026-35414 · CWE-670 · Disclosed 2026-04-02

OpenSSH before 10

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

This is a bad lock on a side door that only exists in houses with a very unusual key system

CVE-2026-35414 is an OpenSSH authorization flaw affecting versions before 10.3. It lives in the uncommon path where sshd trusts a user CA key inside ~/.ssh/authorized_keys using cert-authority plus a principals="..." restriction, and that principals list contains more than one allowed principal. If the trusted CA will issue a certificate whose principal name contains a comma, OpenSSH can mis-match the certificate principals and accept a principal the attacker was not meant to have.

Vendor MEDIUM 4.2 is technically defensible, but operationally it is still too hot for most enterprises. The decisive friction is that this does not hit the main certificate-auth path (TrustedUserCAKeys with AuthorizedPrincipalsFile), and exploitation also requires the attacker to already possess a certificate from a CA the target account explicitly trusts in authorized_keys. That combination makes this a niche authenticated/post-trust edge case, so it scores LOW for patch-priority even though the local impact could be serious on the few hosts that use this pattern.

"Real bug, tiny target set: this is a niche SSH cert auth bypass, not a fleet-wide fire drill"
02 · The Attack Path

4 steps from start to impact.

STEP 01

Find a host using per-user SSH CA trust

The attacker needs a target account whose authorized_keys contains a cert-authority entry with a principals="a,b"-style multi-principal restriction. This is the vulnerable path described by OpenSSH; hosts using TrustedUserCAKeys plus AuthorizedPrincipalsFile are outside scope. Weaponized tooling is just normal OpenSSH auth plumbing in sshd(8).
Conditions required:
  • Target runs OpenSSH earlier than 10.3
  • Target uses certificate auth via cert-authority lines in authorized_keys
  • That line includes principals= with more than one principal
Where this breaks in practice:
  • Most enterprises using SSH certs centralize trust with TrustedUserCAKeys, which OpenSSH says is not affected
  • Internet scanners cannot reliably see per-user authorized_keys content
Detection/coverage: External scanners and banner checks can confirm OpenSSH version, but they cannot confirm this per-user trust pattern from the network.
STEP 02

Obtain a CA-signed certificate with a comma-bearing principal

The attacker must get a certificate from the trusted CA containing a principal name with a comma that can trigger the parser mismatch. OpenSSH explicitly notes exploitation requires a CA that will issue such certificate contents. Weaponized tooling would typically be ssh-keygen -s or the organization's CA issuance workflow.
Conditions required:
  • Attacker can request or obtain a cert from the trusted CA
  • CA policy allows the needed principal encoding
  • Certificate includes a comma-bearing principal that collides with allowed principals
Where this breaks in practice:
  • Typical CAs strongly constrain which principals they issue
  • Many enterprises gate SSH certificate issuance through tightly controlled identity workflows
  • This prerequisite already implies prior trust or a CA-process failure
Detection/coverage: CA issuance logs, SSH certificate serial tracking, and unusual principal values are your best telemetry; vuln scanners generally do not test this safely.
STEP 03

Authenticate with standard ssh client flow

The attacker presents the crafted certificate to sshd, which evaluates the authorized_keys principals="..." restriction using the incorrect matching algorithm. Because of the comma-handling bug, a certificate principal can be accepted as if it matched an allowed principal it should not match. Weaponized tooling is simply the stock ssh client with the issued cert.
Conditions required:
  • Network reachability to SSH
  • A valid CA-signed user certificate
  • A vulnerable matching path in sshd
Where this breaks in practice:
  • High attack complexity: several niche conditions must all line up
  • No user interaction, but also no drive-by path
Detection/coverage: Successful auth will look like valid cert-based login unless you log and review certificate principals, serials, and CA fingerprints.
STEP 04

Land as the wrong account

Impact is an authorization bypass inside the SSH trust model: the attacker logs in as a more privileged or otherwise unauthorized account whose authorized_keys trusted the CA line. Blast radius is constrained to the specific accounts and hosts that use this pattern; it is not a generic pre-auth remote code execution. Post-login impact then depends on local sudo, shell access, and host role.
Conditions required:
  • Mis-match grants access to a meaningful target account
  • That account has useful local privileges or lateral value
Where this breaks in practice:
  • No direct code execution from the bug itself
  • Per-account trust boundaries sharply limit fleet-wide blast radius
Detection/coverage: Review sshd auth logs for certificate logins where the certificate principal set does not make sense for the accessed account; EDR only helps after login.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo public active exploitation evidence found in the sources reviewed, and the CVE is not KEV-listed.
Proof-of-concept availabilityNo authoritative public exploit repo confirmed from primary sources reviewed; the GitHub advisory shows "No known source code".
EPSSExtremely low. Your intel lists 0.00031; GitHub Advisory currently shows about 0.022% / 6th percentile, which is directionally the same: low exploitation probability.
KEV statusNot listed in CISA KEV as of this assessment.
CVSS vectorCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:N — the important parts are High attack complexity and Low privileges required, which translate in practice to *already-trusted attacker with a very specific cert-auth setup*.
Affected versionsOpenSSH < 10.3 per OpenSSH release notes and NVD.
Unaffected auth pathOpenSSH states the main certificate-authentication path using TrustedUserCAKeys and AuthorizedPrincipalsFile is not affected. This matters more than the raw CVSS number.
Fixed versions / backportsUpstream fix is 10.3 / 10.3p1. Examples of distro backports: Ubuntu 24.04 LTS fixed in 1:9.6p1-3ubuntu13.16, Ubuntu 22.04 LTS fixed in 1:8.9p1-3ubuntu0.15, Debian bookworm fixed in 1:9.2p1-2+deb12u10, Debian bullseye fixed in 1:8.4p1-5+deb11u7.
Scanning / exposure realityHard to census from outside. Shodan/Censys can fingerprint SSH exposure, but this bug depends on per-user authorized_keys contents and CA issuance policy, which are not externally observable. Treat external exposure counts as a poor proxy.
ReporterReported by Vladimir Tokarev in the OpenSSH 10.3 release notes / oss-security announcement.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to LOW (2.9/10)

The single biggest downgrade factor is that exploitation requires a trusted SSH certificate issuance path plus a rare per-user authorized_keys CA configuration, not just an exposed SSH port. This is a narrow, post-trust authorization bug with poor external reachability and limited blast radius across real enterprise fleets.

HIGH Exploit preconditions are unusually restrictive
MEDIUM Population estimate of affected real-world deployments

Why this verdict

  • Requires prior trust, not raw reachability: the attacker needs a certificate from a CA the target account already trusts, which is a major downgrade from a pre-auth remote bug.
  • Hits a niche config branch: OpenSSH says the common TrustedUserCAKeys / AuthorizedPrincipalsFile path is not affected; only CA keys trusted via per-user authorized_keys are.
  • Needs a fragile chain of conditions: vulnerable version, multi-principal principals= restriction, CA issuance behavior that permits comma-bearing principal values, and a useful target account all must line up.
  • Blast radius is account-scoped: compromise lands where that specific authorized_keys trust exists, not broadly across every SSH listener on the host.
  • Telemetry and exploit economics are poor for attackers: the vulnerable condition is hard to discover remotely and hard to weaponize at scale, which aligns with the very low EPSS.

Why not higher?

This is not a pre-auth RCE, not a mass-exploitable parser bug, and not even a generic SSH-certificate flaw. The affected population is narrowed by internal configuration choices and CA issuance policy, which compounds the friction well beyond what a vendor CVSS label captures.

Why not lower?

It is still a real authorization bypass, and on the hosts that use this pattern it can authenticate an attacker as the wrong account. If one of those accounts is privileged, the local outcome can be severe even though the exposed population is small.

05 · Compensating Control

What to do — in priority order.

  1. Hunt for cert-authority plus multi-principal principals= lines — Search user authorized_keys files for cert-authority entries that also carry principals="a,b"-style restrictions. This identifies the tiny subset that is actually exposed; for a LOW verdict, do this as backlog hygiene with no SLA.
  2. Prefer central CA trust paths — Where possible, move SSH certificate authorization to TrustedUserCAKeys with AuthorizedPrincipalsFile or AuthorizedPrincipalsCommand, which OpenSSH states is not affected by this bug. For a LOW verdict, make this part of normal hardening backlog hygiene.
  3. Constrain CA issuance policy — Review the SSH CA workflow so it cannot mint unexpected principal values, especially comma-bearing or multi-value principal encodings that create parser edge cases. Do this during routine identity-control review, not as an emergency change.
  4. Log certificate principal details — Increase visibility around SSH certificate serials, principals, and target account mappings so misuse of unusual cert contents is easier to spot. For LOW, roll this into the next logging/telemetry tuning cycle.
What doesn't work
  • A WAF does nothing here; this is SSH authentication logic, not HTTP.
  • Closing public SSH exposure alone is not a full answer, because the bug is just as relevant on internal admin networks if the niche cert-auth pattern exists.
  • Version-only internet scanning overstates risk; seeing OpenSSH_9.x on port 22 does not tell you whether the vulnerable authorized_keys trust model is in use.
06 · Verification

Crowdsourced verification payload.

Run this on the target Linux host as root so it can inspect system and user authorized_keys files. Save as check-cve-2026-35414.sh and run sudo bash check-cve-2026-35414.sh; it returns VULNERABLE when it finds both an unfixed version and a risky cert-authority + multi-principal principals= pattern, PATCHED when the installed package/version is known fixed, and UNKNOWN otherwise.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check-cve-2026-35414.sh
# Best-effort detector for CVE-2026-35414 on Linux/OpenSSH hosts.
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

set -u

status="UNKNOWN"
reason=""
version_src=""
version_val=""
fixed_by_pkg=0
vuln_by_version=0
risky_cfg=0

have_cmd() { command -v "$1" >/dev/null 2>&1; }

log() { printf '%s\n' "$*"; }

# Try package-manager-aware fixed-version checks first for common Debian/Ubuntu cases.
check_dpkg_fixed() {
  have_cmd dpkg-query || return 1
  local pkgver=""
  pkgver=$(dpkg-query -W -f='${Version}\n' openssh-server 2>/dev/null || true)
  if [ -z "$pkgver" ]; then
    pkgver=$(dpkg-query -W -f='${Version}\n' openssh-client 2>/dev/null || true)
  fi
  [ -z "$pkgver" ] && return 1

  version_src="dpkg"
  version_val="$pkgver"

  # Known fixed distro package versions from vendor advisories.
  if dpkg --compare-versions "$pkgver" ge '1:10.3p1-1'; then fixed_by_pkg=1; return 0; fi
  if dpkg --compare-versions "$pkgver" ge '1:10.2p1-2ubuntu3.2'; then fixed_by_pkg=1; return 0; fi
  if dpkg --compare-versions "$pkgver" ge '1:10.0p1-5ubuntu5.4'; then fixed_by_pkg=1; return 0; fi
  if dpkg --compare-versions "$pkgver" ge '1:9.6p1-3ubuntu13.16'; then fixed_by_pkg=1; return 0; fi
  if dpkg --compare-versions "$pkgver" ge '1:8.9p1-3ubuntu0.15'; then fixed_by_pkg=1; return 0; fi
  if dpkg --compare-versions "$pkgver" ge '1:9.2p1-2+deb12u10'; then fixed_by_pkg=1; return 0; fi
  if dpkg --compare-versions "$pkgver" ge '1:8.4p1-5+deb11u7'; then fixed_by_pkg=1; return 0; fi
  if dpkg --compare-versions "$pkgver" ge '1:10.0p1-7+deb13u3'; then fixed_by_pkg=1; return 0; fi

  vuln_by_version=1
  return 0
}

extract_upstream_version() {
  local raw="$1"
  # Extract things like 9.6p1, 10.2, 10.3p1 from package or ssh -V output.
  printf '%s' "$raw" | sed -nE 's/.*OpenSSH[_ ]([0-9]+\.[0-9]+(p[0-9]+)?).*/\1/p; t; s/.*([0-9]+\.[0-9]+(p[0-9]+)?).*/\1/p'
}

ver_ge_10_3() {
  # Returns 0 if version >= 10.3, else 1. Handles forms like 10.3, 10.3p1, 9.9p2.
  local v="$1"
  local major minor
  major=$(printf '%s' "$v" | sed -E 's/^([0-9]+)\..*/\1/')
  minor=$(printf '%s' "$v" | sed -E 's/^[0-9]+\.([0-9]+).*/\1/')
  [ -z "$major" ] && return 1
  [ -z "$minor" ] && return 1
  if [ "$major" -gt 10 ]; then return 0; fi
  if [ "$major" -lt 10 ]; then return 1; fi
  [ "$minor" -ge 3 ]
}

check_raw_version() {
  local raw=""
  if have_cmd ssh; then
    raw=$(ssh -V 2>&1 | head -n1)
  elif have_cmd sshd; then
    raw=$(sshd -V 2>&1 | head -n1)
  fi
  [ -z "$raw" ] && return 1

  version_src="binary"
  version_val="$raw"
  local up
  up=$(extract_upstream_version "$raw")
  [ -z "$up" ] && return 1

  if ver_ge_10_3 "$up"; then
    fixed_by_pkg=1
  else
    vuln_by_version=1
  fi
  return 0
}

scan_authorized_keys() {
  local files=()
  local f

  # Common global and root locations
  [ -f /root/.ssh/authorized_keys ] && files+=(/root/.ssh/authorized_keys)
  [ -f /etc/ssh/authorized_keys ] && files+=(/etc/ssh/authorized_keys)

  # Enumerate local users with home directories
  if [ -r /etc/passwd ]; then
    while IFS=: read -r _ _ _ _ _ home shell; do
      [ -n "$home" ] || continue
      [ -d "$home/.ssh" ] || continue
      [ -f "$home/.ssh/authorized_keys" ] && files+=("$home/.ssh/authorized_keys")
      [ -f "$home/.ssh/authorized_keys2" ] && files+=("$home/.ssh/authorized_keys2")
    done < /etc/passwd
  fi

  for f in "${files[@]}"; do
    [ -r "$f" ] || continue
    if grep -Eqi 'cert-authority' "$f" && grep -Eqi 'principals="[^"]*,[^"]*"' "$f"; then
      risky_cfg=1
      reason="Found cert-authority with multi-principal principals= in $f"
      return 0
    fi
  done
  return 0
}

# Main
check_dpkg_fixed || true
if [ "$fixed_by_pkg" -eq 0 ] && [ "$vuln_by_version" -eq 0 ]; then
  check_raw_version || true
fi

scan_authorized_keys

if [ "$fixed_by_pkg" -eq 1 ]; then
  status="PATCHED"
  if [ -z "$reason" ]; then
    reason="Installed package/version appears fixed (${version_src}: ${version_val})"
  fi
  printf '%s - %s\n' "$status" "$reason"
  exit 0
fi

if [ "$vuln_by_version" -eq 1 ] && [ "$risky_cfg" -eq 1 ]; then
  status="VULNERABLE"
  if [ -z "$reason" ]; then
    reason="Vulnerable version plus risky authorized_keys pattern detected"
  else
    reason="Vulnerable version (${version_src}: ${version_val}) and risky config: ${reason}"
  fi
  printf '%s - %s\n' "$status" "$reason"
  exit 1
fi

status="UNKNOWN"
if [ "$vuln_by_version" -eq 1 ]; then
  reason="Version appears vulnerable (${version_src}: ${version_val}) but no readable risky authorized_keys pattern was confirmed"
else
  reason="Could not determine fixed status from package/version data"
fi
printf '%s - %s\n' "$status" "$reason"
exit 2
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning, do not treat this like an emergency fleet-wide SSH event. First, use config search to find the tiny slice of hosts that actually trust SSH user certificates via per-user authorized_keys cert-authority entries with multi-principal principals= restrictions; if you do not use that pattern, document the rationale and move on. For a LOW verdict, there is no noisgate mitigation SLA and no noisgate remediation SLA — treat this as backlog hygiene, validate exposure in your next auth-hardening review, and roll the actual OpenSSH or distro backport fix through the normal maintenance cycle rather than burning an out-of-band window.

Sources

  1. OpenSSH 10.3 release notes
  2. oss-security announcement for OpenSSH 10.3
  3. NVD entry for CVE-2026-35414
  4. GitHub Advisory Database entry
  5. Ubuntu CVE page with fixed package versions
  6. Debian security tracker entry
  7. OpenBSD sshd_config manual
  8. CISA Known Exploited Vulnerabilities Catalog
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.