← Back to Feed CACHED · 2026-10-26 22:36:14 · CACHE_KEY CVE-2026-115889
CVE-2026-115889 · CWE-197 · Disclosed 2026-10-23

Wasmtime Cranelift compiler SSA index bit-packing overflow enabling sandbox escape

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

A typo in the ruler's measuring tape lets every prisoner walk through the walls

CVE-2026-115889 is a numeric truncation error (CWE-197) in the Cranelift compiler backend used by Wasmtime, the Bytecode Alliance's reference WebAssembly runtime. Cranelift bit-packs SSA (Static Single Assignment) value indices into a fixed-width field — reportedly 24 bits in earlier internal representations. In release builds, Rust's default integer-overflow behavior is wrapping (not panicking), so when a WebAssembly function contains enough SSA values to exceed the bit-packed capacity, the index silently wraps around. The result: Cranelift references the *wrong* IR value during code generation, producing arbitrary miscompilation. Because the miscompiled code runs inside the Wasm sandbox engine itself, an attacker who controls the Wasm module can leverage the resulting type confusion (CWE-843) to read/write outside the sandbox's linear memory, achieving full host-process compromise. All architectures using the default Cranelift backend are affected across Wasmtime versions < 36.0.19 and 37.0.0 through 42.x. Fixes ship in 36.0.19 (LTS backport) and 43.0.0, which upgrade the index to a full u32 with overflow checks.

The vendor's CRITICAL 9.9 rating is aggressive but defensible for Wasmtime's canonical deployment role. Wasmtime exists *specifically* to sandbox untrusted WebAssembly — it is the security boundary, analogous to a hypervisor or container runtime. The CVSS vector AV:N/AC:L/PR:L/UI:N/S:C captures this well: the attacker submits a crafted module over the network with low privileges (a platform tenant account), no user interaction, and the impact crosses from the Wasm guest into the host process (Scope: Changed). Where we trim from 9.9 to 9.4 is on practical grounds: there is no public proof-of-concept, no observed in-the-wild exploitation, the EPSS probability sits at a low 0.45%, and crafting the trigger module requires nontrivial understanding of Cranelift IR internals. These temporal factors reduce immediate operational risk but do not change the fundamental severity class — this remains a CRITICAL sandbox-escape primitive.

"Wasmtime sandbox escape via Cranelift integer overflow — CRITICAL for any host running untrusted Wasm"
02 · The Attack Path

5 steps from start to impact.

STEP 01

Craft oversized-SSA Wasm module

The attacker authors a WebAssembly module containing a function body engineered to produce more SSA values than the bit-packed index field can represent. This could be a single enormous function or a carefully structured function that maximizes SSA value creation through heavy use of locals, intermediate expressions, and control flow. The module must be valid Wasm (pass validation) but is designed to overflow the Cranelift-internal index during compilation.
Conditions required:
  • Attacker can write arbitrary valid WebAssembly bytecode
  • Knowledge of Cranelift SSA index bit-width and overflow behavior
Where this breaks in practice:
  • No public PoC or tooling automates this today
  • Requires reverse-engineering Cranelift IR internals to reliably trigger overflow at a chosen value
STEP 02

Submit module to Wasmtime-powered service

The crafted .wasm binary is submitted to a service that compiles and executes untrusted WebAssembly via Wasmtime with the default Cranelift backend. In edge-compute platforms (Fastly Compute), this is simply deploying a new service. In plugin systems, it is uploading a plugin. The attacker needs whatever credential grants Wasm upload rights — typically a platform tenant account.
Conditions required:
  • Target service accepts attacker-supplied Wasm modules
  • Service uses Wasmtime with Cranelift backend (the default)
  • Attacker holds a valid tenant/user account (PR:L)
Where this breaks in practice:
  • Services that pre-validate or size-limit Wasm functions may reject the oversized module
  • Some platforms use alternative backends (e.g., Winch) or runtimes (V8, Wasmer) not affected
Detection/coverage: WAF or upload-validation layer could flag abnormally large single-function Wasm modules; Cranelift compilation metrics may show anomalous IR sizes
STEP 03

Cranelift compiles with truncated SSA indices

During JIT or AOT compilation, Cranelift's IR builder assigns SSA value indices that exceed the bit-packed field width. In a release build, Rust wraps the integer silently. The truncated index now aliases an earlier, unrelated SSA value. All subsequent optimization passes and code generation operate on the wrong value, producing machine code that performs operations the original Wasm semantics did not intend.
Conditions required:
  • Wasmtime built in release mode (standard for production)
  • Cranelift version < 43.0.0 using bit-packed indices
Where this breaks in practice:
  • Debug builds with overflow checks would panic instead of wrapping — but production deployments universally use release builds
Detection/coverage: No runtime detection; the miscompilation is silent. Post-hoc forensic analysis of generated machine code could identify the aliased value, but this requires deep Cranelift expertise.
STEP 04

Type confusion enables out-of-bounds access

The miscompiled code treats a value of one type as another — for example, interpreting a user-controlled i64 as a pointer, or confusing a bounds-check result with an unchecked value. This breaks Wasm's linear-memory isolation guarantees. The attacker can now read or write memory outside the Wasm sandbox's allocated region, within the host process address space.
Conditions required:
  • The specific SSA alias produces an exploitable type confusion (attacker-influenced by module design)
Where this breaks in practice:
  • Achieving a *specific* useful confusion requires careful alignment of the overflow — trial and error may be needed
  • ASLR on the host adds a probabilistic barrier to reliable exploitation
Detection/coverage: Memory-safety tools (ASan, HWASAN) on the host process could detect OOB access, but these are not used in production due to performance overhead
STEP 05

Sandbox escape to host-process RCE

With arbitrary read/write within the host process, the attacker pivots to full code execution. Standard techniques apply: overwrite function pointers, corrupt vtables, or manipulate Wasmtime's internal data structures to redirect control flow. On multi-tenant platforms, this grants access to other tenants' data and the underlying host OS context. The attacker now operates with the privileges of the Wasmtime host process.
Conditions required:
  • Successful OOB read/write from step 4
  • Host process runs with meaningful privileges (network access, filesystem, secrets)
Where this breaks in practice:
  • CFI/CET on modern CPUs adds friction to control-flow hijacking
  • Seccomp/AppArmor/SELinux policies may limit post-escape lateral movement
Detection/coverage: EDR/host-based IDS may detect anomalous syscalls from the Wasmtime process; runtime integrity monitoring could flag unexpected code execution patterns
03 · Compensating Control

1
CRITICAL 9.4→IGNORE 0.0
SEVERITY REDUCED
Upgrade Wasmtime to 43.0.0+ or 36.0.19 (LTS) immediately — The definitive fix. Cranelift now uses full u32 indices with overflow checks, eliminating the truncation entirely. Per the noisgate mitigation SLA for CRITICAL, deploy within 3 days. This is a Cargo dependency update (cargo update -p wasmtime) followed by rebuild and redeployment. For platforms like Fastly, check that the platform vendor has updated their runtime.
2
CRITICAL 9.4→MEDIUM 5.5
SEVERITY REDUCED
Enforce Wasm function body size limits — Reject Wasm modules where any single function exceeds a conservative IR-size threshold before Cranelift compilation. Wasmtime's Config API allows setting max_function_size or similar resource limits. This prevents the SSA index from reaching overflow. Deploy within 3 days as a stopgap if patching requires more time.
3
CRITICAL 9.4→HIGH 7.5
SEVERITY REDUCED
Run Wasmtime host process in a minimal-privilege sandbox — Wrap the Wasmtime process in seccomp-bpf, AppArmor, or SELinux with a strict allowlist of syscalls and filesystem paths. Even if the Wasm sandbox is escaped, the OS-level sandbox constrains the blast radius. This is defense-in-depth and should already be in place for multi-tenant platforms.
4
CRITICAL 9.4→HIGH 8.0
SEVERITY REDUCED
Enable Wasm module pre-validation and static analysis — Implement a pre-compilation validation step that analyzes the Wasm module's function complexity, local count, and instruction density. Flag modules with anomalously high SSA-generating patterns. This is an imperfect heuristic but raises the bar for exploitation.
What doesn't work
  • Network-level WAF rules — The Wasm module is opaque binary data, typically uploaded via platform-specific APIs. A WAF cannot inspect or understand Wasm bytecode structure to detect the malicious pattern.
  • Switching to debug builds — While debug builds would panic on integer overflow, the 10-100x performance penalty makes this completely impractical for production workloads.
  • ASLR alone — ASLR adds entropy to the host address space but does not prevent the sandbox escape itself. An attacker with arbitrary read can defeat ASLR by leaking pointers before pivoting to write.
04 · Intelligence Metadata

The supporting signals.

In-the-Wild ExploitationNone observed. Not listed in CISA KEV. No reports of active campaigns. The Bytecode Alliance stated no attacks were known at disclosure time.
Proof-of-ConceptNo public PoC. No exploit code found on GitHub, ExploitDB, or pocindex.io. No nuclei template. Crafting a trigger module requires Cranelift-internal knowledge of SSA index bit-packing. Exploitation difficulty is moderate-to-hard without a PoC.
EPSS0.00454 (0.45%) — bottom quartile. The model rates exploitation probability as low, consistent with the niche product and absence of public exploit tooling.
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H — 9.9. Scope:Changed is the key driver: the vuln crosses the Wasm-to-host boundary. PR:L reflects that uploading a Wasm module requires a tenant account, not anonymous access.
Affected VersionsWasmtime < 36.0.19 (all early versions) and 37.0.0 through 42.x (all mainline releases between LTS and v43). This spans roughly two years of releases.
Fixed Versions36.0.19 (LTS backport) and 43.0.0 (mainline). Fix replaces bit-packed indices with full u32 plus overflow checks. See PR #12613 and #14818.
Disclosure TimelineReported 2026-10-19, advisory issued 2026-10-20, CVE published 2026-10-23. Turnaround was fast — 4 days from report to public CVE.
ReporterCredited to jaydns per the GHSA advisory.
Companion CVEDisclosed alongside CVE-2026-115893 (Cranelift br_table with >256K targets causes incorrect branch on aarch64). Same disclosure batch, same fix versions. Check both.
Scanning / ExposureWasmtime is an embedded library/CLI, not a network service with a fingerprint. No Shodan/Censys/GreyNoise tag exists. Exposure assessment requires software inventory (SBOM, cargo audit, package manager queries). Fastly Compute, Shopify, and similar platforms are the highest-profile consumers.

Sources.

  1. GitHub Security Advisory (GHSA-897f-g5gm-fmxm)
  2. RustSec Advisory RUSTSEC-2026-0380
  3. GitLab Advisory Database
  4. The Hacker News — Two Critical Wasmtime Flaws
  5. VulDB — CVE-2026-115889
  6. Bytecode Alliance Wasmtime Security Advisories
  7. Helix Threat Watch — CVE-2026-115889
05 · The Call

Final Verdict
= UNCHANGED to CRITICAL (9.4/10)

Why this verdict

  • Canonical sandbox runtime — floor is CRITICAL. Wasmtime's entire purpose is executing *untrusted* WebAssembly in a sandboxed environment. By definition, the vast majority (>80%) of production Wasmtime deployments are in the high-value role — they ARE the security boundary between untrusted tenant code and the host. A sandbox escape in a sandboxing runtime is analogous to a hypervisor escape in ESXi: the component's reason for existence is the boundary being broken.
  • Role multiplier — edge/serverless platforms (Fastly Compute, Shopify plugins): The documented chain succeeds fully in these deployments. A tenant uploads a crafted module → Cranelift compiles it → sandbox escape → host-process RCE with access to other tenants' data and secrets. Blast radius is fleet-scale / multi-tenant isolation breach. These platforms represent a significant share of Wasmtime's installed base.
  • Role multiplier — CI/CD and plugin sandboxing: Organizations embedding Wasmtime to sandbox build plugins or user-supplied extensions face supply-chain-scale blast radius if the sandbox is escaped. The chain succeeds identically.
  • Scope:Changed is accurate and devastating. The CVSS S:C flag correctly captures that the vulnerability crosses from the Wasm guest context into the host process — this is a privilege boundary violation, not just a local escalation.
  • Downward adjustment from 9.9 to 9.4: No public PoC exists, EPSS is 0.45%, no in-the-wild exploitation observed, and crafting the trigger module requires nontrivial Cranelift-internal knowledge. These temporal factors reduce immediate risk but do not change the severity class.

Why not higher?

The vendor's 9.9 is near the CVSS ceiling. We trim to 9.4 because the absence of any public exploit code, the zero in-the-wild exploitation, and the requirement for Cranelift-specific knowledge to craft a trigger module all reduce the *immediacy* of the threat. A 10.0 or 9.9 would imply trivially exploitable with public tooling, which is not the case today.

Why not lower?

Dropping below CRITICAL would require evidence that few Wasmtime deployments occupy the high-value role — but the opposite is true: Wasmtime exists to sandbox untrusted code, making nearly all deployments high-value by definition. The sandbox escape primitive gives C:H/I:H/A:H with Scope:Changed on a multi-tenant boundary. Even without a public PoC, a motivated attacker (nation-state, ransomware group targeting cloud infrastructure) can develop one. The niche deployment base reduces *breadth* of exposure but not *depth* of impact where Wasmtime is present.

06 · Verification

Crowdsourced verification payload.

Run on any host where Wasmtime is installed as a CLI binary or embedded as a Cargo dependency. Execute from the project root (for Cargo.lock checks) or any shell where wasmtime is in PATH. No special privileges required. Example: bash check_cve_2026_115889.sh

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# CVE-2026-115889 — Wasmtime Cranelift SSA bit-packing overflow checker
# Checks installed wasmtime version against patched versions.
# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN
set -euo pipefail

echo "=== CVE-2026-115889 Wasmtime Version Check ==="
VER=""
SOURCE=""

# Method 1: wasmtime CLI binary
if command -v wasmtime &>/dev/null; then
    VER=$(wasmtime --version 2>/dev/null | grep -oP '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
    SOURCE="wasmtime CLI"
fi

# Method 2: Cargo.lock dependency
if [ -z "$VER" ] && [ -f "Cargo.lock" ]; then
    VER=$(grep -A1 'name = "wasmtime"' Cargo.lock 2>/dev/null | grep 'version' | head -1 | sed 's/.*"\([0-9.]*\)".*/\1/')
    SOURCE="Cargo.lock"
fi

# Method 3: cargo tree
if [ -z "$VER" ] && command -v cargo &>/dev/null && [ -f "Cargo.toml" ]; then
    VER=$(cargo tree -p wasmtime 2>/dev/null | head -1 | grep -oP '[0-9]+\.[0-9]+\.[0-9]+' || true)
    SOURCE="cargo tree"
fi

if [ -z "$VER" ]; then
    echo "UNKNOWN — wasmtime not found (not in PATH, Cargo.lock, or Cargo.toml)"
    exit 2
fi

echo "Detected wasmtime $VER via $SOURCE"

IFS='.' read -r MAJOR MINOR PATCH <<< "$VER"

# Patched: (>= 43.0.0) OR (>= 36.0.19 AND < 37.0.0)
# Vulnerable: (< 36.0.19) OR (>= 37.0.0 AND < 43.0.0)
if [ "$MAJOR" -ge 43 ]; then
    echo "PATCHED — $VER >= 43.0.0"
    exit 0
elif [ "$MAJOR" -eq 36 ] && [ "$MINOR" -eq 0 ] && [ "$PATCH" -ge 19 ]; then
    echo "PATCHED — $VER >= 36.0.19 (LTS backport)"
    exit 0
elif [ "$MAJOR" -ge 37 ] && [ "$MAJOR" -lt 43 ]; then
    echo "VULNERABLE — $VER is in range 37.x-42.x; upgrade to >= 43.0.0"
    exit 1
elif [ "$MAJOR" -eq 36 ]; then
    if [ "$MINOR" -gt 0 ] || [ "$PATCH" -lt 19 ]; then
        echo "VULNERABLE — $VER < 36.0.19; upgrade to >= 36.0.19 or >= 43.0.0"
        exit 1
    fi
elif [ "$MAJOR" -lt 36 ]; then
    echo "VULNERABLE — $VER < 36.0.19; upgrade to >= 36.0.19 or >= 43.0.0"
    exit 1
fi

echo "UNKNOWN — could not classify version $VER"
exit 2