← Back to Feed CACHED · 2026-10-26 05:25:47 · CACHE_KEY CVE-2026-34486
CVE-2026-34486 · CWE-311 · Disclosed 2026-04-09

Apache Tomcat Tribes EncryptInterceptor fail-open bypass enabling unauthenticated RCE via deserialization

ASSESSED — NOISGATE
Vendor
—
—
—
Reassessed
—
—
—
Verdict: —
Do you agree?
01 · The Real Story

A one-line regression turned Tomcat's encryption guard into an open door — and attackers walked right through it

CVE-2026-34486 is a fail-open regression in Apache Tomcat's EncryptInterceptor, the component that encrypts Tribes cluster-to-cluster traffic. The fix for CVE-2026-29146 (a padding oracle) accidentally moved super.messageReceived(msg) outside the try-catch block in EncryptInterceptor.messageReceived(). When decryption of an inbound cluster message fails, the exception is caught and logged — but execution continues, forwarding the attacker's raw, unencrypted bytes straight into XByteBuffer.deserialize(), which calls bare ObjectInputStream.readObject() with no ObjectInputFilter. An attacker who can reach the Tribes NioReceiver (default TCP/4000) can send a crafted Java serialized object — typically a CommonsCollections6 gadget chain via ysoserial — and achieve unauthenticated remote code execution as the Tomcat process user. Exactly three point releases carry the regression: 9.0.116, 10.1.53, and 11.0.20. Fixed in 9.0.117, 10.1.54, and 11.0.21 (released April 2–4, 2026).

The vendor rated this Important / HIGH 7.5 with a CVSS vector of AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N — modeling only the *encryption bypass* (confidentiality loss) without accounting for the downstream deserialization-to-RCE chain. That is a material understatement. The actual exploitation outcome is full remote code execution with no authentication, no user interaction, and complete compromise of the host. CISA agreed: the KEV entry carries a 3-day remediation due date (August 7, 2026). The EPSS score of 0.985 places this in the top 1.5% of all CVEs for predicted exploitation probability, and Unit 42 has attributed active exploitation to the China-nexus actor knaithe (UNC5174/UNC6586), deploying SNOWLIGHT malware via an AI-driven scanning campaign. The vendor's 7.5 score dangerously undersells the real risk.

"Vendor called it info-disclosure; the real chain is unauthenticated RCE. KEV-listed, actively exploited by APT."
02 · The Attack Path

5 steps from start to impact.

STEP 01

Locate exposed Tribes receiver

The attacker scans for TCP/4000 (the default NioReceiver port for Tomcat Tribes clustering). This port speaks a binary Tribes protocol and is trivially distinguishable from HTTP. In the knaithe campaign, automated scanning via the Hermes agent framework targeted 460+ hosts. Shodan/Censys dorks for this port are straightforward, though most Tribes ports are internal-facing.
Conditions required:
  • Target runs Tomcat 9.0.116, 10.1.53, or 11.0.20
  • Tribes clustering is enabled in server.xml
  • TCP/4000 (or configured receiver port) is network-reachable from attacker
Where this breaks in practice:
  • Tribes clustering is not enabled by default — requires explicit <Cluster> configuration
  • Port 4000 is rarely internet-facing; typically restricted to internal cluster VLAN
  • Only 3 specific point versions carry the regression
Detection/coverage: Network IDS rules matching Tribes protocol handshake on non-cluster source IPs; ss -ltnp | grep :4000 on host inventory scans
STEP 02

Send malformed Tribes frame with serialized payload

The attacker constructs a Tribes protocol frame containing a Java serialized object instead of legitimate encrypted cluster data. The PoC (exp.py from 404-src/CVE-2026-34486) uses TribesClient.java to build a valid Tribes frame header and embeds a CommonsCollections6 gadget chain generated by ysoserial-all.jar. The 1496-byte frame is sent directly to the receiver port. No authentication, no TLS negotiation, no shared secret is required.
Conditions required:
  • Network path to Tribes receiver port
  • ysoserial or equivalent payload generator
  • Knowledge of target's classpath gadgets (CC6 is a safe bet for most Tomcat deployments)
Where this breaks in practice:
  • Attacker must guess or enumerate available gadget libraries (though CommonsCollections is near-ubiquitous on Tomcat)
  • Custom Tribes frame construction required (but PoC code handles this)
Detection/coverage: Log signature: SEVERE...Failed to decrypt message...IllegalBlockSizeException: Input length must be multiple of 16 — this is the only indicator; the subsequent deserialization succeeds silently
STEP 03

EncryptInterceptor fails open

The EncryptInterceptor.messageReceived() method attempts to decrypt the incoming message. Because the attacker sent raw (unencrypted) bytes, decryption throws a GeneralSecurityException (typically AEADBadTagException or IllegalBlockSizeException). The catch block logs the error — but super.messageReceived(msg) sits outside the try block, so execution continues. The original attacker-controlled bytes in the message buffer are forwarded up the interceptor chain unchanged.
Conditions required:
  • EncryptInterceptor is configured on the cluster channel (ironically, unpatched clusters *without* EncryptInterceptor were already vulnerable to direct deserialization via CVE-2025-24813)
Where this breaks in practice:
  • Only organizations that proactively configured EncryptInterceptor — typically security-conscious shops — carry this specific regression
  • The bug was present for ~14 days in Maven Central before the fix shipped
Detection/coverage: The decryption-failure log entry above is generated at this step. No deserialization exception follows — the payload executes cleanly.
STEP 04

Deserialization triggers gadget chain

The forwarded bytes reach XByteBuffer.deserialize(), which calls ObjectInputStream.readObject() with no ObjectInputFilter. The CommonsCollections6 chain (or any compatible gadget) executes its transformer chain, invoking Runtime.getRuntime().exec() or equivalent. The attacker achieves arbitrary command execution as the Tomcat process user — typically tomcat, root (in Docker), or a service account with access to application secrets, database credentials, and session stores.
Conditions required:
  • A usable deserialization gadget library on the Tomcat classpath (CommonsCollections 3.x/4.x, Spring, Groovy, etc.)
Where this breaks in practice:
  • Tomcat ships with commons-collections in many default webapp deployments; removing it breaks applications
  • Modern JDK serialization filters (jdk.serialFilter) could block this if configured, but almost nobody sets them on Tomcat
Detection/coverage: RASP/agent-based detection of ObjectInputStream.readObject() from network-sourced data; EDR alerting on child processes spawned by java with Tomcat classpath
STEP 05

Post-exploitation: pivot across cluster

With RCE on one cluster node, the attacker has access to the shared EncryptInterceptor key (stored in server.xml or referenced keystore), all replicated HTTP sessions, JDBC connection pool credentials, and network adjacency to every other cluster member. The knaithe campaign deployed SNOWLIGHT malware at this stage — a lightweight implant providing persistent backdoor access. From the compromised node, the attacker can replay the same exploit against sibling cluster nodes (they share the same vulnerable version and gadget libraries) or pivot to backend databases and internal services.
Conditions required:
  • Successful RCE from step 4
Where this breaks in practice:
  • Network segmentation between Tomcat tier and backend databases may limit lateral movement
  • Host-based EDR should detect SNOWLIGHT binary drop or suspicious java child processes
Detection/coverage: EDR process-tree monitoring; outbound C2 connection detection; anomalous Tribes traffic patterns between cluster nodes
03 · Compensating Control

1
CRITICAL 9.0→LOW 3.1
SEVERITY REDUCED
Firewall Tribes receiver port to cluster-only sources — Restrict TCP/4000 (or your configured Receiver port) to only the IP addresses of legitimate cluster members via host firewall (iptables/nftables/Windows Firewall) or network security group. This breaks the attack path at step 1 by preventing attacker packets from reaching the vulnerable code. Deploy within the noisgate mitigation SLA of 3 days for CRITICAL severity. This is the single highest-ROI control if you cannot patch immediately.
2
CRITICAL 9.0→IGNORE 0.0
SEVERITY REDUCED
Upgrade to patched Tomcat (9.0.117 / 10.1.54 / 11.0.21+) — The definitive fix moves super.messageReceived(msg) back inside the try block, ensuring failed decryptions discard the message. Apply within the noisgate remediation SLA of 90 days — though given KEV status, aim for days not weeks. Verify the fix with the provided script.
3
CRITICAL 9.0→IGNORE 0.0
SEVERITY REDUCED
Disable Tribes clustering if not actively used — If <Cluster> is configured in server.xml but session replication is not required (e.g., sticky sessions via load balancer suffice), remove or comment out the <Cluster> element and restart Tomcat. This eliminates the entire attack surface. Many Tomcat deployments have clustering configured from a template but never operationally use it.
4
CRITICAL 9.0→HIGH 7.0
SEVERITY REDUCED
Remove or replace CommonsCollections from classpath — The weaponized PoCs use the CommonsCollections6 gadget chain. Removing commons-collections-3.x.jar or upgrading to commons-collections4 with InvokerTransformer removed breaks the known exploit chains. However, this is fragile — other gadget libraries (Spring, Groovy, BeanUtils) may also be exploitable, and removing CC3 may break applications. Treat this as defense-in-depth, not a primary control.
5
CRITICAL 9.0→MEDIUM 5.5
SEVERITY REDUCED
Configure JDK serialization filter — Set jdk.serialFilter in CATALINA_OPTS or jdk.serialFilter system property to reject dangerous classes (e.g., !org.apache.commons.collections.functors.*). This adds a defense layer at the JVM level against deserialization gadgets. Requires JDK 9+ or JDK 8u121+. Note: filter must be carefully tuned to avoid breaking legitimate Tribes deserialization.
6
CRITICAL 9.0→CRITICAL 9.0
Monitor for decryption-failure log signatures — Alert on EncryptInterceptor log entries containing Failed to decrypt message, IllegalBlockSizeException, AEADBadTagException, or BadPaddingException. These are the only observable indicators of exploitation attempts — the subsequent deserialization and command execution produce no log output. Feed to SIEM with high-priority alerting. This is a detection control, not a prevention control.
What doesn't work
  • WAF / reverse proxy in front of HTTP port — The attack targets the Tribes clustering port (TCP/4000), not the HTTP/HTTPS port (8080/8443). A WAF inspecting HTTP traffic will never see the malicious Tribes frames.
  • TLS termination on the load balancer — TLS protects HTTP traffic to Tomcat, not internal Tribes cluster communication. The Tribes protocol has its own encryption layer (EncryptInterceptor), which is exactly what this CVE bypasses.
  • Java Security Manager — Deprecated since JDK 17 and removed in JDK 24. Even where available, it was rarely configured restrictively enough to block Runtime.exec() from deserialization contexts. Do not rely on it.
  • Upgrading to the initially-fixed versions (9.0.116, 10.1.53, 11.0.20) — These ARE the vulnerable versions. Organizations that patched for CVE-2026-29146 by upgrading to these releases inadvertently introduced CVE-2026-34486. You must go one version further.
04 · Intelligence Metadata

The supporting signals.

In-the-wild statusActively exploited. CISA added CVE-2026-34486 to the KEV catalog on 2026-08-04 with a 3-day due date (2026-08-07). Palo Alto Unit 42 attributes exploitation to knaithe (UNC5174/UNC6586), a China-nexus actor using an AI-driven campaign via the DeepSeek model and Hermes agent framework, targeting 460+ hosts. SOCRadar reports a Taiwan-focused campaign deploying SNOWLIGHT malware via CommonsCollections6 deserialization.
Proof-of-conceptMultiple weaponized PoCs public. striga-ai/CVE-2026-34486 — Docker-based reproduction with CC6 payload. 404-src/CVE-2026-34486 — exp.py script using ysoserial CC6 chain, TribesClient.java for frame construction. Both include full exploit chains from payload generation to command execution validation. karczewski.io published a video PoC walkthrough.
EPSS0.98503 — top 1.5% of all scored CVEs. This places CVE-2026-34486 in the highest exploitation-probability tier, consistent with its KEV listing and weaponized PoC availability.
KEV statusListed. Added 2026-08-04, due date 2026-08-07 (3-day window). Required action: apply vendor mitigations per BOD 26-04. Not flagged for ransomware use.
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N (vendor, 7.5). This vector models only the encryption bypass / confidentiality loss. It does not capture the downstream deserialization-to-RCE chain (which would add I:H/A:H). A more accurate RCE-inclusive vector with clustering prerequisites: AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H = 8.1, or AC:L for deployments where clustering is already exposed = 9.8.
Affected versionsExactly three point releases: Apache Tomcat 9.0.116, 10.1.53, 11.0.20. These were the latest releases when the regression shipped. Earlier versions are NOT affected by this specific CVE (though they may carry CVE-2026-29146 or other cluster deserialization issues). Tomcat 8.5.x is unaffected.
Fixed versions9.0.117 (2026-04-03), 10.1.54 (2026-04-02), 11.0.21 (2026-04-04). Distro backports: RHEL/CentOS — see Red Hat advisory; SUSE — SUSE KB.
Scanning/exposureTribes receiver port (TCP/4000) is typically internal-facing and not indexed by Shodan/Censys at scale. No public internet-wide scan statistics available. The knaithe campaign used automated recon against internal networks and cloud VPCs rather than internet-wide scanning. Individual sightings reported (e.g., exposed directory on 150.40.117[.]90:8000 with Tribes indicators).
Disclosure timeline2026-02-22: CVE-2026-29146 reported → 2026-03-26: CVE-2026-34486 regression reported → 2026-04-02–04: Fixes released → 2026-04-09: Public disclosure → 2026-08-04: CISA KEV addition
Reporting / attributionOriginal vulnerability reported to Apache. Exploitation attributed by Palo Alto Unit 42 to knaithe (UNC5174/UNC6586). Campaign used DeepSeek AI model through Hermes agent framework for automated scanning and exploitation.

Sources.

  1. Apache Tomcat 11 Security Advisories (vendor)
  2. CISA KEV Alert — CVE-2026-34486 Added
  3. 404-src/CVE-2026-34486 — Weaponized PoC (exp.py + ysoserial)
  4. striga-ai/CVE-2026-34486 — Docker reproduction lab
  5. Corgea Research — Root cause analysis with KEV context
  6. johal.in — One-line diff deep dive
  7. SOCRadar — SNOWLIGHT campaign attribution
  8. Red Hat Security Advisory
05 · The Call

Final Verdict
↑ UPGRADED to CRITICAL (9.0/10)

Why this verdict

  • Vendor underscore is structurally wrong. The vendor CVSS (7.5) models *only* the encryption bypass (C:H/I:N/A:N). The documented, reproducible, and actively exploited chain ends in unauthenticated remote code execution — the correct impact tuple is C:H/I:H/A:H. This alone would push the base score to 9.8 if attack complexity were Low.
  • KEV-listed with the shortest possible CISA deadline. Added 2026-08-04 with a 3-day remediation due date (2026-08-07), confirming CISA's assessment that this is an actively exploited, high-impact vulnerability requiring emergency response.
  • EPSS 0.985 confirms weaponization. An EPSS score in the top 1.5% is not a theoretical risk — it reflects observed exploitation patterns, public PoC maturity, and attacker adoption rates consistent with the multiple weaponized exploit repositories.
  • APT-grade exploitation in active campaigns. Unit 42's attribution to knaithe (UNC5174/UNC6586) with AI-driven scanning and SNOWLIGHT malware deployment demonstrates this is not opportunistic scanning — it is targeted, persistent, and operationally mature.
  • Clustering prerequisite narrows population but not severity. Tribes clustering is not default-enabled, and port 4000 is typically internal. However, where clustering IS enabled, it is invariably in production high-availability environments handling sensitive session data and backend credentials — exactly the environments where RCE matters most.
  • Role multiplier: Apache Tomcat is the dominant Java application server. When Tribes clustering is configured, the deployment is by definition a production HA tier — category (b) at minimum. In many enterprises, Tomcat cluster nodes serve as the application layer for ERP, CRM, healthcare, and financial applications. Compromise of one node yields: (1) all replicated sessions across the cluster, (2) JDBC credentials for backend databases, (3) the shared EncryptInterceptor key enabling exploitation of every sibling node. This is application-tier-scale blast radius. In organizations running Jenkins on Tomcat (common legacy pattern), this becomes CI/CD-scale — a supply-chain pivot. The production-HA deployment pattern means ≥80% of affected installs (those running clustering) occupy category (b) or higher roles.
  • Gadget availability is near-universal. CommonsCollections 3.x ships with or alongside most Tomcat webapp deployments. The CC6 chain used in public PoCs works out-of-the-box against the vast majority of real Tomcat classpaths.

Why not higher?

A 10.0 would require zero prerequisites and universal exposure. This vulnerability requires Tribes clustering to be explicitly enabled (not default), port 4000 to be network-reachable, and a deserialization gadget library on the classpath. While all three conditions are commonly met in production clustering deployments, they do meaningfully narrow the vulnerable population to a subset of all Tomcat installations — perhaps 5–15% of the installed base.

Why not lower?

Downgrading below CRITICAL would require dismissing the confirmed active exploitation by a nation-state-attributed APT, the KEV listing with a 3-day deadline, the EPSS score of 0.985, and the demonstrated RCE outcome. The clustering prerequisite is a population limiter, not a complexity barrier — where clustering is enabled, exploitation is trivial (send one packet, get shell). The vendor's 7.5 HIGH rating is based on an incomplete impact model that ignores the deserialization chain entirely.

06 · Verification

Crowdsourced verification payload.

Run this script on each Tomcat host as any user with read access to the Tomcat installation directory. Invoke: bash check_cve_2026_34486.sh /opt/tomcat (pass your CATALINA_HOME as the first argument). No root required unless server.xml is root-readable only.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_cve_2026_34486.sh — Detect CVE-2026-34486 exposure
# Usage: bash check_cve_2026_34486.sh /path/to/catalina_home
# Exit codes: 1=VULNERABLE, 0=PATCHED, 2=UNKNOWN

set -euo pipefail

CATALINA_HOME="${1:-}"
if [ -z "$CATALINA_HOME" ]; then
  echo "Usage: $0 <CATALINA_HOME>"
  exit 2
fi

# --- Determine Tomcat version ---
VERSION_FILE="$CATALINA_HOME/lib/catalina.jar"
if [ ! -f "$VERSION_FILE" ]; then
  echo "[UNKNOWN] Cannot find catalina.jar at $CATALINA_HOME/lib/"
  exit 2
fi

VERSION=$(unzip -p "$VERSION_FILE" org/apache/catalina/util/ServerInfo.properties 2>/dev/null \
  | grep '^server.number=' | cut -d= -f2 | tr -d '[:space:]')

if [ -z "$VERSION" ]; then
  echo "[UNKNOWN] Could not extract Tomcat version from catalina.jar"
  exit 2
fi

echo "[INFO] Detected Tomcat version: $VERSION"

# --- Check if version is one of the three affected releases ---
VULN_VERSIONS="9.0.116 10.1.53 11.0.20"
IS_VULN_VERSION=false
for v in $VULN_VERSIONS; do
  if [ "$VERSION" = "$v" ]; then
    IS_VULN_VERSION=true
    break
  fi
done

if [ "$IS_VULN_VERSION" = false ]; then
  echo "[PATCHED] Tomcat $VERSION is not one of the affected versions (9.0.116, 10.1.53, 11.0.20)."
  exit 0
fi

echo "[WARNING] Tomcat $VERSION is an affected version."

# --- Check if Tribes clustering is enabled ---
SERVER_XML="$CATALINA_HOME/conf/server.xml"
if [ ! -f "$SERVER_XML" ]; then
  echo "[UNKNOWN] Cannot find server.xml at $SERVER_XML"
  exit 2
fi

CLUSTER_ENABLED=false
if grep -qiE '<Cluster\b|SimpleTcpCluster|DeltaManager|BackupManager' "$SERVER_XML" 2>/dev/null; then
  # Check it's not commented out
  if grep -E '<Cluster\b|SimpleTcpCluster' "$SERVER_XML" | grep -qvE '^\s*<!--'; then
    CLUSTER_ENABLED=true
  fi
fi

if [ "$CLUSTER_ENABLED" = false ]; then
  echo "[PATCHED] Tomcat $VERSION detected but Tribes clustering is NOT enabled in server.xml."
  echo "[INFO] The EncryptInterceptor bypass is not reachable without clustering. Low risk."
  exit 0
fi

echo "[WARNING] Tribes clustering IS enabled."

# --- Check if EncryptInterceptor is configured ---
ENCRYPT_CONFIGURED=false
if grep -qiE 'EncryptInterceptor' "$SERVER_XML" 2>/dev/null; then
  if grep -E 'EncryptInterceptor' "$SERVER_XML" | grep -qvE '^\s*<!--'; then
    ENCRYPT_CONFIGURED=true
  fi
fi

if [ "$ENCRYPT_CONFIGURED" = true ]; then
  echo "[WARNING] EncryptInterceptor IS configured — fail-open bypass is active."
else
  echo "[WARNING] EncryptInterceptor is NOT configured — cluster traffic is unencrypted."
  echo "[INFO] CVE-2026-34486 specifically requires EncryptInterceptor, but unencrypted"
  echo "       clustering is arguably worse (direct deserialization with no encryption at all)."
fi

# --- Check if receiver port is listening ---
RECEIVER_PORT=4000
CUSTOM_PORT=$(grep -oP 'Receiver[^>]*port="\K[0-9]+' "$SERVER_XML" 2>/dev/null | head -1)
if [ -n "$CUSTOM_PORT" ]; then
  RECEIVER_PORT=$CUSTOM_PORT
fi

PORT_OPEN=false
if command -v ss &>/dev/null; then
  if ss -ltnp 2>/dev/null | grep -q ":${RECEIVER_PORT} "; then
    PORT_OPEN=true
  fi
elif command -v netstat &>/dev/null; then
  if netstat -tlnp 2>/dev/null | grep -q ":${RECEIVER_PORT} "; then
    PORT_OPEN=true
  fi
fi

if [ "$PORT_OPEN" = true ]; then
  echo "[WARNING] Tribes receiver port $RECEIVER_PORT is LISTENING."
else
  echo "[INFO] Tribes receiver port $RECEIVER_PORT does not appear to be listening (Tomcat may not be running)."
fi

# --- Final verdict ---
echo ""
echo "=== RESULT ==="
if [ "$CLUSTER_ENABLED" = true ]; then
  echo "[VULNERABLE] Tomcat $VERSION with Tribes clustering enabled."
  echo "  Action: Upgrade immediately to 9.0.117 / 10.1.54 / 11.0.21+"
  echo "  Interim: Firewall port $RECEIVER_PORT to cluster members only."
  exit 1
else
  echo "[PATCHED] Vulnerable version detected but clustering not enabled. Not exploitable."
  exit 0
fi