The Miscompile Was the Escape: Two 9.9 Cranelift Flaws Let a Crafted Wasm Module Break Out of Wasmtime
On 19 October 2026, the Bytecode Alliance published two security advisories against its own compiler. Both concern Cranelift, the backend Wasmtime uses by default to turn WebAssembly into machine code, and both carry the same verdict: a user-controlled Wasm module can escape the sandbox. CVE-2026-115889 (GHSA-897f-g5gm-fmxm) works on every architecture; CVE-2026-115893 (GHSA-mghf-wjfp-p5xm) is ARM64-only. Each is scored 9.9 Critical under CVSS 3.1 (AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H). The NVD records for both went live on 23 October. We read both advisories and both NVD entries first-hand, in full.
Wasmtime runs WebAssembly outside the browser, which is exactly where the trust boundary sits for agent platforms, edge compute and serverless Wasm: the host compiles modules written by other people. The advisories name no affected downstream service, and the maintainers report no attacks. But the precondition is ordinary rather than exotic — hand the engine a module you control — so anyone running a multi-tenant Wasm platform should treat this as patch-now material. This is a different defect class from the one we covered in runwasi’s CVE-2026-47218, where the sandbox was bypassed at the container-layer boundary; here the compiler itself produced the wrong program.
The bit-packing bug: silent overflow in release builds
CVE-2026-115889 is the more conceptually uncomfortable of the two. Before Wasmtime 43, Cranelift bit-packed the indices it uses to track values (SSA values) inside a function into fields narrower than the index — 24-bit fields, in the reporting. In release builds, an index too large for its field overflowed silently, with no error, and Cranelift went on to reference the wrong value in its intermediate representation. Wrong values mean arbitrary miscompilation, and arbitrary miscompilation means type confusion and whatever attacker-controlled effects follow. The trigger is a very large function body, or one crafted to use many SSA values; the advisory credits reporter jaydns and lists CWE-197 (numeric truncation) alongside CWE-843 (type confusion).
Two details in the advisory deserve attention. First, the report itself carries the line “This report was submitted with AI assistance” — one more entry in the ledger of machine-assisted auditing finding real compiler bugs, and worth filing next to the AI-found hardening work we have been tracking elsewhere. Second, the fixed line is old: Cranelift moved to a full 32-bit index, with a check if that limit is exceeded, in the Wasmtime 43 development line, which shipped as 43.0.0 on 20 March. The advisory’s affected range is therefore split — below 36.0.19, and from 37.0.0 up to but not including 43.0.0 — with 36.0.19 named as the patched release. The change that removed the bug was authored as ordinary compiler work months before anyone attached a CVE to it; the advisory does not say when the security impact was recognised.
The ARM64 bug: a quarter-million jump targets, one wrong branch
CVE-2026-115893 is narrower in platform and broader in history. On aarch64, Cranelift could compile a Wasm br_table instruction carrying more than roughly 256,000 targets so that an out-of-range index was sent to the default target through a conditional branch that can only reach a limited distance. The branch then lands on arbitrary other code at a user-controlled offset, and the sandbox is gone. The weakness is listed as CWE-691 (insufficient control-flow management), and the reporter credit goes to ilyas-mallah.
The exposure window is the striking part: the advisory states that every Wasmtime and Cranelift version supporting aarch64 since that support began in 2020 — before Wasmtime 1.0 — is affected. Six years of releases, one miscompiled branch. Patches are 36.0.19, 48.0.7 and 49.0.4, and Wasmtime 50.0.0, released 20 October, ships fixed for both flaws. Hosts that applied the April ARM64 Cranelift fixes (36.0.7, 42.0.2, 43.0.1) for an earlier sandbox escape are still affected by this one — a reminder that “patched for the last compiler bug” is not a durable state when the compiler is the attack surface.
The patch matrix nobody will enjoy
Wasmtime’s release-line structure turns two advisories into a routing exercise, and the version table compiled from the advisories and the NVD entries is worth reproducing carefully:
- 36.0.19 — fixed for both flaws. If you are on the 36 LTS line, this is your target.
- 37.0.0 through 42.x — affected by both. Move to 48.0.7, 49.0.4 or 50.0.0.
- 43.0.0 through 47.x — not affected by the bit-packing bug, affected by the ARM64 bug. Move on ARM64 hosts regardless.
- 48.0.0 through 48.0.6 — update to 48.0.7. 49.0.0 through 49.0.3 — update to 49.0.4.
- 24.x and everything else unsupported — no fix. Only the 36, 48, 49 and 50 lines are still supported; the 24.x LTS line’s support ended on 20 August 2026.
Three operational points follow. First, updating the wasmtime CLI does not fix anything that embeds Wasmtime as a library — and Wasmtime is designed to be embedded. Every program that includes it must be rebuilt against a fixed release. This is the same bundled-copy lesson the Brotli disclosure taught last week, when we noted in the .NET out-of-band release that updating a system library leaves vendored copies exposed; it applies with full force here. Second, neither advisory lists a workaround — until the host is updated, any module an outsider can supply is in scope. Third, the support-window arithmetic is unforgiving: long-term-support lines are numbered in multiples of 12 and kept for two years, everything else gets two months, so a large fraction of deployed lines have exactly one move available, which is off the line entirely.
The Dependabot blind spot
Both flaws are registered in RustSec — RUSTSEC-2026-0380 for the bit-packing bug, RUSTSEC-2026-0379 for the ARM64 bug — so cargo-audit users are covered. GitHub’s advisory database is a different story: as of 26 October it carries a reviewed entry for CVE-2026-115889 but none for CVE-2026-115893, and GitHub states that only reviewed entries trigger Dependabot alerts. If your ARM64 estate depends on Dependabot to notice this class of bug, it will not notice this one. That is not a criticism of the reviewers — triage queues are finite — but it is a concrete gap to close with a direct version check rather than an assumption.
One downstream data point shows the fix propagating: the serverless Wasm platform Spin moved to Wasmtime 50.0.0 in version 4.2.4 on 21 October. If you run Spin, that release is your exit. More broadly, anyone offering compute over customer-supplied modules on Wasmtime — the advisories pointedly decline to name names — should be able to answer which release line their hosts sit on and whether the CLI they updated is the same artifact their platform embeds. If those are two different answers, only one of them matters.
What to do with this
- Inventory your Wasmtime release line first, patch second. The fix you need depends on the line: 36.0.19, 48.0.7, 49.0.4 or 50.0.0. Lines outside 36/48/49/50 must migrate.
- Rebuild embedders, not just the CLI. Audit every binary that links Wasmtime as a library and rebuild it against a fixed release; a patched toolchain on the build host does not patch shipped artifacts.
- Do not rely on Dependabot for the ARM64 flaw. CVE-2026-115893 has no reviewed GitHub advisory entry, so check aarch64 hosts directly.
- Treat any outsider-supplied module as in scope until patched. There are no workarounds in either advisory, and neither flaw requires anything beyond the ability to get the engine to compile a hostile module.
Verification note: Bytecode Alliance advisories GHSA-897f-g5gm-fmxm (CVE-2026-115889) and GHSA-mghf-wjfp-p5xm (CVE-2026-115893), both published 19 October 2026 by pchickey, were read first-hand and in full, including affected and patched version ranges, severity metrics, weakness enumerations and reporter credits. The NVD records for both CVEs (published 23 October 2026; the 115889 record last modified 26 October) were read first-hand and confirm the descriptions, the 9.9 CVSS 3.1 vectors and the fix releases. The claim that the defect-removing change merged on 18 February and shipped in Wasmtime 43.0.0 on 20 March, the claim that Spin 4.2.4 adopted Wasmtime 50.0.0 on 21 October, the RustSec identifiers, the Dependabot reviewed-entry behaviour, the April ARM64 fix versions and the absence of reported exploitation and of KEV listing are carried as reported by The Hacker News on 26 October and are labelled as such where they appear. No Wasm module was written, compiled or run against any Wasmtime build; no host, platform or downstream service was contacted or tested; no advisory text is reproduced beyond short attributed facts. The reading of the bundled-copy exposure and of the Dependabot gap as operational risks is our analysis. Brave Search was used for discovery only; every consequential claim was re-verified against the two GitHub advisories and the two NVD records.
Sources:
- Bytecode Alliance / wasmtime — GHSA-897f-g5gm-fmxm, “Bit-packing in Cranelift compiler causes silent overflow and miscompilation” (CVE-2026-115889, published 19 October 2026)
- Bytecode Alliance / wasmtime — GHSA-mghf-wjfp-p5xm, “Cranelift backend on aarch64 can jump to incorrect target on large Wasm br_table instruction” (CVE-2026-115893, published 19 October 2026)
- NVD — CVE-2026-115889 (published 23 October 2026)
- NVD — CVE-2026-115893 (published 23 October 2026)
- The Hacker News — “Two Critical Wasmtime Flaws Could Let Malicious WebAssembly Modules Escape Sandboxes” (26 October 2026)