This is a bad lock on the server room door, but only after the attacker is already inside and holding the keyring
CVE-2026-31681 is a Linux kernel netfilter/xt_multiport validation flaw in the rule-checking path for malformed multiport v1 rules. Upstream affected ranges published by NVD are 2.6.17 to <6.6.136, 6.7 to <6.12.83, 6.13 to <6.18.24, 6.19 to <6.19.14, plus 7.0-rc1 through 7.0-rc7. The bug is in how the kernel validates port-range encoding before accepting a rule, so the practical trigger is rule insertion via iptables/xtables-compatible paths, not ordinary network traffic.
Reality is lower than a generic vendor 'HIGH' label. This is *local* and, more importantly, it effectively assumes the attacker can already create firewall rules—typically root, CAP_NET_ADMIN, or a badly over-privileged container. That makes it a post-initial-access kernel DoS/memory-safety bug with a narrow reachable population, not an internet-scale intrusion path.
4 steps from start to impact.
Land code execution on a Linux host
AV:L assessment.- Local shell, malware foothold, or container access on a Linux system
- Host is running an affected kernel branch
- No pre-auth remote entry point in the CVE itself
- A lot of enterprise Linux exposure dies right here because the attacker needs prior compromise
310347); perimeter scanners will not find it.Gain firewall-rule management rights
xt_multiport checkentry path, the attacker needs to submit crafted multiport rules with a tool such as iptables or an xtables-compatible path. In real deployments that usually means root or CAP_NET_ADMIN, which is a much narrower condition than 'low privilege' sounds on paper.CAP_NET_ADMIN,root, or equivalent firewall-management privilegext_multiportsupport present as built-in or module
- Default unprivileged users cannot normally add netfilter rules
- Many hardened containers drop
NET_ADMIN, blocking exploitation from container footholds - Some hosts may not have
xt_multiportenabled or used
iptables/ip6tables invocation or capability abuse better than vuln scanners can.Insert a malformed xt_multiport v1 rule
ports_match_v1() walks past the last valid ports[] element while interpreting the rule. The weaponized primitive here is the crafted iptables rule itself, not special packet content.- Attacker can call
iptables/xtables APIs successfully - Kernel accepts the relevant matcher path
- Rule syntax has to reach the vulnerable path cleanly
- Config differences between legacy iptables, nft backends, and distro backports may break public exploit portability
Crash or destabilize the kernel path
- Successful malformed-rule insertion on a vulnerable kernel
- Memory layout cooperates enough for a fault or corruption side effect
- Public sources do not show a reliable privilege-escalation exploit chain
- Most evidence points to DoS-class impact, not turnkey root from a normal user
dmesg, journalctl -k, crash dumps, and EDR signals for kernel oops/panic following netfilter or iptables activity.The supporting signals.
| In-the-wild status | No CISA KEV entry surfaced for CVE-2026-31681, and I found no confirmed active exploitation reports in the primary sources reviewed. |
|---|---|
| Proof-of-concept availability | I found no public GitHub PoC or weaponized exploit repo. GitHub's advisory (GHSA-f822-mpgr-7cqx) is present, but it is unreviewed and does not publish exploit code. |
| EPSS | Very low. Third-party mirrors of FIRST data show roughly 0.01%–0.02% EPSS and about the 3rd–5th percentile; the exact value varies by snapshot, but the risk signal is consistently near the floor. |
| KEV status | Not listed in the CISA Known Exploited Vulnerabilities Catalog in the sources reviewed. |
| CVSS and what it means | CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H = local, some privilege already needed, and mostly availability impact. That is a strong downgrade signal for enterprise patch priority. |
| Affected versions | NVD lists upstream Linux kernel exposure in 2.6.17 to <6.6.136, 6.7 to <6.12.83, 6.13 to <6.18.24, 6.19 to <6.19.14, and 7.0-rc1..rc7. |
| Fixed versions | Upstream fixes landed by stable branch at 6.6.136, 6.12.83, 6.18.24, 6.19.14, and mainline 7.0 according to NVD/kernel patch references. |
| Distro reality | Debian still showed bullseye and bookworm as vulnerable in the tracker snapshot reviewed, while trixie, forky, and sid had fixed versions. Ubuntu marked many package families as either Vulnerable, Not in release, or Ignored, which is why distro backport status matters more than bare uname -r. |
| Exposure / scanning | This is not meaningfully internet-scannable. Tenable ships it as a local plugin, which is exactly right: exposure depends on host compromise plus firewall-rule privileges, not open ports discoverable by Shodan/Censys/FOFA. |
| Disclosure | Published 2026-04-25 by the Linux CNA / kernel.org supply chain, with later NVD enrichment on 2026-05-06. |
noisgate verdict.
The decisive factor is the attacker position requirement: exploitation effectively assumes the attacker can already manage host firewall rules, which usually means root or CAP_NET_ADMIN. That collapses the reachable population from 'every Linux host on the internet' to a much smaller set of already-compromised or over-privileged systems.
Why this verdict
- Post-compromise requirement: The bug is local-only (
AV:L) and starts after the attacker already has code execution on the host or container. - Privilege friction compounds: Reaching the vulnerable path generally implies
iptablesrule creation rights, which in practice meansroot/CAP_NET_ADMIN, not a normal user. - No exploitation heat: No KEV listing, no public PoC, and very low EPSS all argue against emergency treatment.
- Blast radius is mostly availability: The public scoring and descriptions point mainly to DoS-class impact rather than a clean, reliable privilege-escalation chain.
Why not higher?
If this were reachable by network traffic alone or usable by any unprivileged local user, it would climb fast. But stacking local foothold + firewall admin capability + specific kernel matcher path is exactly the sort of compounding friction that drags real-world severity down.
Why not lower?
It is still kernel-space memory-safety in a widely deployed component, and the impact can be a host crash. Also, some containerized or appliance-style deployments hand out NET_ADMIN too freely, which makes this more reachable than a purely root-only kernel bug.
What to do — in priority order.
- Strip
CAP_NET_ADMINfrom containers — RemoveNET_ADMINfrom Kubernetes pods, Docker containers, and service wrappers unless there is a documented need. That directly cuts off the most realistic enterprise attack path; for a LOW verdict there is no mitigation SLA, so treat this as backlog hygiene and complete it during the next hardening cycle. - Lock down firewall administration — Restrict
iptables/nftchanges to trusted administrators and audited automation only. Usesudo, RBAC, and config-management guardrails so malware or low-trust operators cannot reach the vulnerable rule-insertion path; for LOW, there is no mitigation SLA, so fold this into normal platform-hardening work. - Prioritize admin-heavy Linux tiers for kernel updates — Focus first on bastions, network appliances, container hosts, and any node where operators or workloads legitimately manipulate netfilter rules. These are the small subset where the CVE is actually reachable; for LOW, there is no mitigation SLA, so schedule through routine maintenance.
- Monitor for unauthorized rule writes — Alert on
iptables,ip6tables,nft, and changes to netfilter configuration from unexpected parents, users, or containers. This won't patch the flaw, but it gives you a practical tripwire for the prerequisite behavior; for LOW, there is no mitigation SLA, so implement as standard detection engineering.
- A WAF or edge firewall does not help; the bug is not triggered by inbound packets hitting an exposed service.
- External attack-surface scanning does not help; this is a local kernel condition and Tenable correctly models it as a local plugin.
- Dropping user-space package updates only does not fix the running kernel if the vulnerable kernel image remains deployed.
Crowdsourced verification payload.
Run this on the target Linux host as root or with enough rights to read /boot/config-*, /proc/config.gz, package metadata, and kernel logs if needed. Invoke it as sudo bash cve-2026-31681-check.sh; it performs a conservative offline assessment and prints VULNERABLE, PATCHED, or UNKNOWN.
#!/usr/bin/env bash
# CVE-2026-31681 conservative checker
# Output: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -euo pipefail
KREL="$(uname -r)"
BASE="${KREL%%-*}"
ARCH="$(uname -m)"
OS_ID="unknown"
OS_VER=""
OS_CODENAME=""
if [[ -r /etc/os-release ]]; then
. /etc/os-release
OS_ID="${ID:-unknown}"
OS_VER="${VERSION_ID:-}"
OS_CODENAME="${VERSION_CODENAME:-}"
fi
have_xt_multiport="unknown"
if command -v modinfo >/dev/null 2>&1 && modinfo xt_multiport >/dev/null 2>&1; then
have_xt_multiport="yes"
elif [[ -r /proc/config.gz ]] && zgrep -Eq '^CONFIG_NETFILTER_XT_MATCH_MULTIPORT=(y|m)$' /proc/config.gz; then
have_xt_multiport="yes"
elif [[ -r "/boot/config-$KREL" ]] && grep -Eq '^CONFIG_NETFILTER_XT_MATCH_MULTIPORT=(y|m)$' "/boot/config-$KREL"; then
have_xt_multiport="yes"
else
have_xt_multiport="no"
fi
if [[ "$have_xt_multiport" == "no" ]]; then
echo "PATCHED: xt_multiport support not present on running kernel ($KREL)"
exit 0
fi
ver_ge() { printf '%s\n%s\n' "$2" "$1" | sort -V -C; }
ver_lt() { ! ver_ge "$1" "$2"; }
# Debian-specific assessment from Debian tracker snapshot
if [[ "$OS_ID" == "debian" ]]; then
case "$OS_CODENAME" in
bullseye|bookworm)
echo "VULNERABLE: Debian $OS_CODENAME was listed vulnerable for CVE-2026-31681 in the reviewed tracker snapshot; running kernel=$KREL"
exit 1
;;
trixie)
if ver_ge "$BASE" "6.12.85"; then
echo "PATCHED: Debian trixie running kernel $KREL is at/above reviewed fixed branch floor 6.12.85"
exit 0
else
echo "VULNERABLE: Debian trixie running kernel $KREL is below reviewed fixed branch floor 6.12.85"
exit 1
fi
;;
sid|forky)
if ver_ge "$BASE" "7.0.10"; then
echo "PATCHED: Debian $OS_CODENAME running kernel $KREL is at/above reviewed fixed floor 7.0.10"
exit 0
else
echo "UNKNOWN: Debian $OS_CODENAME detected but package/backport mapping is ambiguous for kernel $KREL"
exit 2
fi
;;
esac
fi
# Upstream-only version gate. Conservative: distro backports can invalidate this.
# If this looks like a distro kernel (has a suffix after the upstream base), prefer UNKNOWN.
if [[ "$KREL" != "$BASE" ]]; then
echo "UNKNOWN: distro kernel detected ($KREL). Upstream version math alone is unreliable because vendors backport fixes. xt_multiport=$have_xt_multiport"
exit 2
fi
vuln=no
if ver_ge "$BASE" "2.6.17" && ver_lt "$BASE" "6.6.136"; then
vuln=yes
fi
if ver_ge "$BASE" "6.7" && ver_lt "$BASE" "6.12.83"; then
vuln=yes
fi
if ver_ge "$BASE" "6.13" && ver_lt "$BASE" "6.18.24"; then
vuln=yes
fi
if ver_ge "$BASE" "6.19" && ver_lt "$BASE" "6.19.14"; then
vuln=yes
fi
case "$BASE" in
7.0.rc1|7.0-rc1|7.0.rc2|7.0-rc2|7.0.rc3|7.0-rc3|7.0.rc4|7.0-rc4|7.0.rc5|7.0-rc5|7.0.rc6|7.0-rc6|7.0.rc7|7.0-rc7)
vuln=yes
;;
esac
if [[ "$vuln" == "yes" ]]; then
echo "VULNERABLE: upstream kernel $KREL falls in reviewed CVE-2026-31681 affected ranges and xt_multiport is present"
exit 1
fi
echo "PATCHED: upstream kernel $KREL is outside the reviewed affected ranges"
exit 0
If you remember one thing.
iptables/nft administration is delegated to operators, automation, or containers with NET_ADMIN; tighten that exposure during normal hardening, because for a LOW verdict there is no noisgate mitigation SLA. Then roll the actual kernel fix through standard maintenance windows—there is likewise no noisgate remediation SLA for LOW, so treat it as backlog hygiene, with extra attention to bastions, container hosts, and network-function nodes where the prerequisite privileges are actually present.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.