← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
tenable:234554 · CWE-440 · Disclosed 2025-04-09

OpenSSH < 10

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

This is a deadbolt that fails only after you already handed someone the front-door key

This is CVE-2025-32728 in sshd: in OpenSSH 7.4 through 9.9 / before 10.0, the DisableForwarding directive failed to block X11 forwarding and agent forwarding as documented. The bug lives in a policy control, not in authentication or packet parsing, so the vulnerable population is really the subset of hosts that both run an affected OpenSSH build and deliberately use DisableForwarding yes to constrain a user or match block.

Tenable calling this LOW is basically right. The real-world attack chain is narrow: the attacker already needs an SSH session or valid credentials, the environment has to rely on this specific directive, and OpenSSH upstream notes that X11 forwarding is disabled by default on the server while agent forwarding is off by default on the client. That combination crushes reachability and makes this a control-bypass bug, not an internet-scale SSH break.

"Real bug, but it only matters when you already trust a user enough to give them SSH and rely on DisableForwarding."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Get an SSH foothold with ssh

The attacker first needs a valid SSH login path: stolen credentials, an approved contractor account, a shared admin key, or some earlier post-compromise foothold. This is not pre-auth and not anonymous internet exploitation; the bug only becomes reachable after the SSH session is established.
Conditions required:
  • Valid SSH credentials or another post-initial-access route
  • Target runs affected OpenSSH sshd before 10.0
Where this breaks in practice:
  • MFA, PAM controls, cert-based auth, and IP allowlists frequently gate SSH access
  • This prerequisite already implies the attacker is past the outer perimeter
Detection/coverage: Standard vuln scanners catch the version, but almost none prove the attacker can satisfy the auth prerequisite.
STEP 02

Land on an account constrained by DisableForwarding

The bug matters only when defenders intentionally depend on DisableForwarding yes, often in a Match block or restricted account policy. If that directive is absent, there is no policy being bypassed and the version finding is mostly noise.
Conditions required:
  • DisableForwarding yes is configured for the target user/session
  • The account can establish a normal SSH session
Where this breaks in practice:
  • Many fleets never use DisableForwarding at all
  • Some orgs use other restrictions like forced commands, jump hosts, or separate bastion roles instead
Detection/coverage: Remote scanners usually cannot see whether DisableForwarding is actually configured; host-side config review is required.
STEP 03

Request forwarding with built-in ssh -A or ssh -X

Once logged in, the attacker uses native OpenSSH client features such as ssh -A for agent forwarding or ssh -X / -Y for X11 forwarding. Because of the logic error, the server may still honor these channels despite DisableForwarding being set.
Conditions required:
  • Client requests agent forwarding or X11 forwarding
  • The relevant forwarding path is otherwise enabled in the environment
Where this breaks in practice:
  • OpenSSH upstream says agent forwarding is off by default in the client
  • OpenSSH upstream says X11 forwarding is disabled by default in the server
  • Even where technically possible, many enterprise users never invoke -A or -X
Detection/coverage: SSH daemon logs and session telemetry may show forwarded-channel creation, but most vuln scanners do not actively validate this behavior.
STEP 04

Turn the bypass into lateral movement

The main practical payoff is not direct code execution on the target host; it is policy bypass. A forwarded agent can let the attacker authenticate onward as the victim user where downstream systems trust agent-backed auth, and X11 forwarding can open access that defenders thought they had denied.
Conditions required:
  • The victim has a loaded SSH agent or actually uses X11 workflows
  • Downstream systems accept the forwarded agent or X11 path
Where this breaks in practice:
  • Many server-side sessions have no agent loaded at all
  • Modern bastion patterns, session recording, and short-lived certs reduce the usefulness of forwarded auth material
Detection/coverage: Good bastion telemetry, EDR on jump boxes, and SSH session audit logs are the best place to spot abuse; network perimeter tools are weak here because this happens inside encrypted SSH.
03 · Intelligence Metadata

The supporting signals.

CVE / bug classCVE-2025-32728, CWE-440 Expected Behavior Violation. This is a documented-behavior failure in sshd, not memory corruption.
DisclosurePublic on 2025-04-09 via OpenSSH 10.0 release / security notes; NVD shows publication on 2025-04-09.
Affected versionsOpenSSH upstream says 7.4 to 9.9 inclusive are affected; NVD models this as 7.4 up to, but excluding, 10.0.
Fixed versionsUpstream fixed in 10.0. Backports exist, including Ubuntu 24.04: 1:9.6p1-3ubuntu13.11, Ubuntu 22.04: 1:8.9p1-3ubuntu0.13, Debian 12 bookworm-security: 1:9.2p1-2+deb12u5, Debian 11 bullseye-security/LTS: 1:8.4p1-5+deb11u5.
Vendor scoring mismatchTenable rates the plugin LOW / 3.8 using the NVD-style vector, while MITRE/Ubuntu show 4.3 MEDIUM. The disagreement is mostly about whether the flaw is modeled as needing privileges; in practice, it is still a narrow post-auth policy bypass.
Defaults that cut riskOpenSSH upstream explicitly notes X11 forwarding is disabled by default in the server and agent forwarding is off by default in the client. That strips out a huge chunk of nominally vulnerable hosts.
In-the-wild statusI found no KEV listing and no credible active-exploitation reporting for this CVE as of 2026-06-01. CISA's weekly bulletin listed it as a newly published vulnerability, not as a known-exploited one.
PoC / weaponizationNo major Metasploit or vendor-backed exploit tooling surfaced in the sources reviewed. Public discussion exists, but exploitation is basically just using stock ssh -A / ssh -X against a host that trusted DisableForwarding to block them.
EPSSPrimary FIRST EPSS query results were not directly retrievable here; third-party mirrors place it around 0.27% EPSS and roughly 50th percentile, i.e. low-to-middle exploit-likelihood signal, which matches the weak real-world reachability.
Exposure / scanner realitySSH is broadly internet-facing in enterprise and provider environments, so version scanners will flag a lot of systems. But this is not an exposure-driven CVE: public port 22 alone does not make the bug materially exploitable unless the host uses DisableForwarding and the attacker already has a session.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to LOW (2.7/10)

The decisive factor is the attacker-position requirement: this only matters after the adversary already has SSH access or valid credentials. On top of that, the bug only bites where defenders intentionally depend on DisableForwarding, and upstream defaults leave both X11 and agent forwarding off in many real deployments.

HIGH This is not an internet-scale pre-auth OpenSSH event
MEDIUM Exact enterprise prevalence of `DisableForwarding yes` in production sshd configs

Why this verdict

  • Step-1 friction: requires authenticated remote access — that means this is already post-initial-access or dependent on valid credentials, which is immediate downward pressure from the vendor baseline.
  • Step-2 friction: requires a specific policy dependency — only hosts that actually use DisableForwarding yes are exposed in practice. Version-only scanner hits overcount badly.
  • Step-3 friction: the forwarded features are not universally on — upstream says X11 forwarding is off by default server-side and agent forwarding is off by default client-side, so the reachable population shrinks again.

Why not higher?

There is no unauthenticated remote entry point here, no memory corruption, no pre-auth parser bug, and no direct code execution path. Even successful abuse typically yields a policy bypass or lateral-movement helper, not instant host takeover.

Why not lower?

I would not mark it IGNORE because some enterprises really do use DisableForwarding to fence in contractors, vendors, or semi-trusted shell users on bastions. If you rely on that control, this bug defeats a security boundary you thought you had.

05 · Compensating Control

What to do — in priority order.

  1. Turn off agent forwarding where you can — Set AllowAgentForwarding no server-side for sensitive roles and keep ForwardAgent no as the client default. For a LOW finding there is no mitigation SLA; deploy this as backlog hygiene in the next normal hardening cycle, prioritizing bastions and shared admin jump boxes.
  2. Disable X11 forwarding on servers that do not need it — Set X11Forwarding no broadly and only carve out exceptions for known legacy workflows. Again, for a LOW verdict there is no mitigation SLA; fold this into your next routine SSH baseline review.
  3. Audit every use of DisableForwarding yes — Find the users, groups, and Match blocks that rely on this control and treat those hosts as the only meaningful patch population. With a LOW verdict, do this during normal config hygiene rather than emergency change windows.
  4. Prefer stronger account restrictions for semi-trusted shells — Where possible, pair SSH restrictions with forced commands, limited groups, session recording, or bastion-only access so that a single forwarding-control bug does not become your only containment layer. For LOW, implement as part of planned access-control improvement work.
What doesn't work
  • A WAF does nothing here; the abuse happens after SSH authentication inside encrypted SSH channels.
  • Simply hiding SSH behind a non-standard port does not matter; the key issue is post-auth policy bypass, not opportunistic internet scanning.
  • Version-only scanning alone is weak evidence because distro backports and the absence of DisableForwarding both create false urgency.
06 · Verification

Crowdsourced verification payload.

Run this on the target Linux host that provides sshd, ideally as root or with sudo so package metadata and /etc/ssh can be read reliably. Save as check-cve-2025-32728.sh and run sudo bash check-cve-2025-32728.sh; it prints exactly VULNERABLE, PATCHED, or UNKNOWN based on package/backport status plus whether DisableForwarding yes is actually used.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check-cve-2025-32728.sh
# Purpose: assess practical exposure to OpenSSH DisableForwarding bug (CVE-2025-32728)
# Output: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

set -u

status_unknown() { echo "UNKNOWN"; exit 2; }
status_vuln() { echo "VULNERABLE"; exit 1; }
status_patched() { echo "PATCHED"; exit 0; }

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

# Convert OpenSSH upstream version like 9.9p1 or 10.0p2 to sortable integer.
ver_to_int() {
  local v="$1"
  v="${v%%p*}"
  local major minor patch
  major="${v%%.*}"
  minor="${v#*.}"
  if [[ "$minor" == "$v" ]]; then minor=0; fi
  patch=0
  printf "%03d%03d%03d\n" "$major" "$minor" "$patch"
}

upstream_ge_10() {
  local raw="$1"
  [[ -z "$raw" ]] && return 1
  local cur target
  cur="$(ver_to_int "$raw")"
  target="$(ver_to_int "10.0")"
  [[ "$cur" -ge "$target" ]]
}

sshd_ver_raw=""
if have_cmd sshd; then
  sshd_ver_raw="$(sshd -V 2>&1 | sed -n 's/.*OpenSSH_\([0-9][0-9.]*p\{0,1\}[0-9]*\).*/\1/p' | head -n1)"
fi
if [[ -z "$sshd_ver_raw" ]] && have_cmd ssh; then
  sshd_ver_raw="$(ssh -V 2>&1 | sed -n 's/.*OpenSSH_\([0-9][0-9.]*p\{0,1\}[0-9]*\).*/\1/p' | head -n1)"
fi
[[ -z "$sshd_ver_raw" ]] && status_unknown

# Detect whether the host actually relies on DisableForwarding.
uses_disableforwarding="no"
for f in /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf; do
  [[ -r "$f" ]] || continue
  if grep -Eiq '^\s*DisableForwarding\s+yes\b' "$f"; then
    uses_disableforwarding="yes"
    break
  fi
done

# If distro packaging tells us it is fixed via backport, trust that over upstream version.
if have_cmd dpkg-query && have_cmd dpkg; then
  pkg_ver="$(dpkg-query -W -f='${Version}\n' openssh-server 2>/dev/null | head -n1)"
  if [[ -n "$pkg_ver" ]]; then
    . /etc/os-release 2>/dev/null || true
    distro_id="${ID:-}"
    distro_ver="${VERSION_ID:-}"

    case "$distro_id:$distro_ver" in
      ubuntu:24.04)
        dpkg --compare-versions "$pkg_ver" ge '1:9.6p1-3ubuntu13.11' && status_patched
        ;;
      ubuntu:22.04)
        dpkg --compare-versions "$pkg_ver" ge '1:8.9p1-3ubuntu0.13' && status_patched
        ;;
      ubuntu:20.04)
        dpkg --compare-versions "$pkg_ver" ge '1:8.2p1-4ubuntu0.13' && status_patched
        ;;
      ubuntu:24.10)
        dpkg --compare-versions "$pkg_ver" ge '1:9.7p1-7ubuntu4.3' && status_patched
        ;;
      ubuntu:25.04|ubuntu:25.10|ubuntu:26.04)
        dpkg --compare-versions "$pkg_ver" ge '1:9.9p1-3ubuntu3.1' && status_patched
        ;;
      debian:12)
        dpkg --compare-versions "$pkg_ver" ge '1:9.2p1-2+deb12u5' && status_patched
        ;;
      debian:11)
        dpkg --compare-versions "$pkg_ver" ge '1:8.4p1-5+deb11u5' && status_patched
        ;;
    esac
  fi
fi

# Generic upstream check. Note: backported RPM builds may be fixed even if upstream version < 10.0.
if upstream_ge_10 "$sshd_ver_raw"; then
  status_patched
fi

# Practical exposure decision:
# - vulnerable version + DisableForwarding in use => VULNERABLE
# - vulnerable version + DisableForwarding unused => PATCHED (not exposed in practice)
if [[ "$uses_disableforwarding" == "yes" ]]; then
  status_vuln
else
  status_patched
fi
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning, query the fleet for DisableForwarding yes and isolate the true patch population to bastions, jump hosts, vendor-access shells, and any semi-trusted SSH accounts that rely on that control. If you do not use the directive, document the finding as low-value version noise and move on; if you do use it, patch those hosts in the next normal maintenance cycle and consider disabling agent/X11 forwarding where unnecessary. Under the noisgate mitigation SLA, there is no mitigation SLA — treat this as backlog hygiene; under the noisgate remediation SLA, there is no SLA for LOW findings, so close it during routine patching rather than emergency change windows.

Sources

  1. Tenable Nessus Plugin 234554
  2. NVD CVE-2025-32728
  3. OpenSSH Security Page
  4. OpenSSH Release Notes
  5. Ubuntu CVE-2025-32728
  6. Debian bug / bookworm fix discussion
  7. Debian LTS Advisory DLA-4156-1
  8. AppSecure CVE-2025-32728 mirror (EPSS reference)
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.