ADR 0037: Wasmtime CVE risk register
Status: Accepted Date: 2026-07-23 Issue: #463
Context
Arbitraitor uses Wasmtime as its primary plugin runtime (ADR-0006). The
arbitraitor-plugin-host crate depends on wasmtime with
default-features = false and the cranelift, runtime, component-model,
parallel-compilation, and cache features. The experimental-wasm feature
gate is off by default. The resolved version in Cargo.lock is
wasmtime 49.0.1 (direct dependency; a second, transitive copy at
45.0.3 is pinned by yara-x 1.20.0).
On 2026-04-09 the Bytecode Alliance published a batch of 12 security advisories for Wasmtime. Two are Critical (CVSS 9.0):
- CVE-2026-34971 / GHSA-jhxm-h53p-jm7w — Cranelift aarch64 miscompilation enabling sandbox escape via arbitrary host-memory read/write.
- CVE-2026-34987 / GHSA-xx5w-cvp6-jv83 — Winch compiler backend sandbox-escaping memory access on aarch64.
Both allow a malicious WebAssembly guest module to read or write arbitrary host memory, defeating the sandbox boundary that ADR-0006 relies on for plugin isolation. Spec §41.9.1 governs Wasmtime plugin execution but has no risk register tying compiler/backend selection and version to security guarantees.
This ADR establishes that risk register as a versioned, living document.
Decision
Adopt a versioned Wasmtime CVE risk register cataloging all known advisories from official sources (GitHub Security Advisories, RustSec, NVD/CVE). The register is maintained in this ADR and updated whenever a new Wasmtime advisory is published or the pinned version changes.
Pinned version
| Field | Value |
|---|---|
| Crate | wasmtime |
| Cargo.toml constraint | >=47.0.4 (security floor, ADR-0040) |
| Resolved version (Cargo.lock) | 49.0.1 |
| Transitive yara-x copy | 45.0.3 (yara-x 1.20.0 requires wasmtime ^45.0.3; RUSTSEC-2026-0222/0269/0316 ignored with rationale) |
| Features enabled | cranelift, runtime, component-model, parallel-compilation, cache |
| Features disabled (default-features = false) | WASI, ambient filesystem, networking, all ambient capabilities |
| Feature gate | experimental-wasm (off by default) |
| Minimum safe version | 47.0.4 (per RUSTSEC-2026-0268/0269 fix ranges) |
Risk register
All advisories below are sourced from the Bytecode Alliance GitHub Security
Advisories page (https://github.com/bytecodealliance/wasmtime/security/advisories)
and the RustSec advisory database (https://rustsec.org/advisories/). The
“Affected?” column reflects whether the pinned versions (49.0.1 direct,
45.0.3 yara-x-pinned transitive) are vulnerable.
Critical
| CVE / GHSA / RUSTSEC | Severity | Affected versions | Fixed | Description | Affected? |
|---|---|---|---|---|---|
| CVE-2026-34971 / GHSA-jhxm-h53p-jm7w / RUSTSEC-2026-0096 | Critical (9.0) | >=32.0.0, <36.0.7; >=37.0.0, <42.0.2; >=43.0.0, <43.0.1 | 36.0.7, 42.0.2, 43.0.1 | Cranelift aarch64 miscompiles load(iadd(base, ishl(index, amt))) when wasm_memory64 is enabled and Spectre mitigations are disabled, creating divergent bounds-check vs. load addresses. Enables arbitrary host-memory read/write (sandbox escape). | No — direct 49.0.1 / transitive 45.0.3 — both >= 43.0.1 |
| CVE-2026-34987 / GHSA-xx5w-cvp6-jv83 / RUSTSEC-2026-0095 | Critical (9.0) | >=25.0.0, <36.0.7; >=37.0.0, <42.0.2; >=43.0.0, <43.0.1 | 36.0.7, 42.0.2, 43.0.1 | Winch compiler backend assumes upper bits of a 32-bit memory offset stored in a 64-bit register are cleared when they may not be. Allows guest Wasm to access memory before/after the linear-memory sandbox. Observed PoC on aarch64; x86-64 theoretical. | No — direct 49.0.1 / transitive 45.0.3 — both >= 43.0.1, and Winch is not enabled |
High
| CVE / GHSA / RUSTSEC | Severity | Affected versions | Fixed | Description | Affected? |
|---|---|---|---|---|---|
| GHSA-vqjp-4c8c-hfgg / RUSTSEC-2026-0269 | High (8.8) | <24.0.13; >=25.0.0, <36.0.14; >=37.0.0, <46.0.3; >=47.0.0, <47.0.4 | 24.0.13, 36.0.14, 46.0.3, 47.0.4 | Filesystem sandbox escape when paths or symlinks contain trailing slashes. | Direct copy: No — resolved 49.0.1. Transitive yara-x copy (45.0.3): Yes — ignored in deny.toml with rationale (no patched yara-x release; formal evaluation in ADR-0040). |
| GHSA-2r75-cxrj-cmph / RUSTSEC-2026-0149 | High (7.5) | wasmtime-wasi <24.0.9; >=36.0.10, <37.0.0; >=44.0.2, <45.0.0; <46.0.0 | 24.0.9, 36.0.10, 44.0.2, 46.0.0 | WASI path_open(TRUNCATE) bypasses FilePerms::WRITE host restriction. | No — wasmtime-wasi not in dependency tree (default-features = false) |
Moderate
| CVE / GHSA / RUSTSEC | Severity | Affected versions | Fixed | Description | Affected? |
|---|---|---|---|---|---|
| CVE-2026-34941 / GHSA-hx6p-xpx3-jvvv / RUSTSEC-2026-0093 | Moderate (6.9) | <24.0.7; >=36.0.7, <37.0.0; >=42.0.2, <43.0.0; <43.0.1 | 24.0.7, 36.0.7, 42.0.2, 43.0.1 | Heap OOB read in component model UTF-16 to latin1+utf16 string transcoding. | No — direct 49.0.1 / transitive 45.0.3 — both >= 43.0.1 |
| GHSA-394w-hwhg-8vgm / RUSTSEC-2026-0091 | Moderate (6.1) | <24.0.7; >=36.0.7, <37.0.0; >=42.0.2, <43.0.0; <43.0.1 | 24.0.7, 36.0.7, 42.0.2, 43.0.1 | OOB write or crash when transcoding component model strings. | No — direct 49.0.1 / transitive 45.0.3 — both >= 43.0.1 |
| GHSA-q49f-xg75-m9xw / RUSTSEC-2026-0089 | Moderate | <43.0.1 | 43.0.1 | Host panic when Winch compiler executes table.fill. | No — direct 49.0.1 / transitive 45.0.3 — both >= 43.0.1, and Winch is not enabled |
| GHSA-qqfj-4vcm-26hv | Moderate | <43.0.1 | 43.0.1 | Segfault or unused out-of-sandbox load with f64x2.splat on Cranelift x86-64. | No — direct 49.0.1 / transitive 45.0.3 — both >= 43.0.1 |
| GHSA-f984-pcp8-v2p7 / RUSTSEC-2026-0094 | Moderate | <43.0.1 | 43.0.1 | Improperly masked return value from table.grow with Winch compiler backend. | No — direct 49.0.1 / transitive 45.0.3 — both >= 43.0.1, and Winch is not enabled |
| GHSA-jxhv-7h78-9775 / RUSTSEC-2026-0092 | Moderate | <43.0.1 | 43.0.1 | Panic when transcoding misaligned component model UTF-16 strings. | No — direct 49.0.1 / transitive 45.0.3 — both >= 43.0.1 |
| GHSA-m758-wjhj-p3jq | Moderate | <43.0.1 | 43.0.1 | Panic when lifting flags component value. | No — direct 49.0.1 / transitive 45.0.3 — both >= 43.0.1 |
| GHSA-p8xm-42r7-89xg | Moderate | <43.0.1 | 43.0.1 | Panic when allocating a table exceeding the size of the host’s address space. | No — direct 49.0.1 / transitive 45.0.3 — both >= 43.0.1 |
| GHSA-243v-98vx-264h | Moderate | <41.0.4 | 41.0.4 | Panic adding excessive fields to a wasi:http/types.fields instance. | No — direct 49.0.1 / transitive 45.0.3 — both >= 41.0.4 |
| GHSA-xjhv-v822-pf94 / RUSTSEC-2026-0022 | Moderate (6.9) | >=39.0.0, <40.0.4; >=40.0.4, <41.0.0 | 40.0.4, 41.0.4 | Panic when dropping a [Typed]Func::call_async future. | No — direct 49.0.1 / transitive 45.0.3 — both >= 41.0.4 |
| GHSA-852m-cvvp-9p4w / RUSTSEC-2026-0020 | Moderate (6.9) | <24.0.6; >=36.0.6, <37.0.0; >=40.0.4, <41.0.0 | 24.0.6, 36.0.6, 40.0.4, 41.0.4 | Guest-controlled resource exhaustion in WASI implementations. | No — direct 49.0.1 / transitive 45.0.3 — both >= 41.0.4 |
| GHSA-vc8c-j3xm-xj73 | Moderate | <25.0.0 | 25.0.0 | Segfault or unused out-of-sandbox load with f64.copysign on x86-64. | No — direct 49.0.1 / transitive 45.0.3 — both >= 25.0.0 |
| GHSA-4ch3-9j33-3pmj | Moderate | wasmtime-wasi <46.0.0 | 46.0.0 | WASI hard links and renames bypass FilePerms for destination. | No — wasmtime-wasi not in dependency tree |
| GHSA-x84v-gj2h-g759 / RUSTSEC-2026-0268 | Moderate (6.9) | >=46.0.0, <46.0.3; >=47.0.0, <47.0.4 | 46.0.3, 47.0.4 | Guest controlled-size host heap allocation through WASIp3 streams. | No — direct copy 49.0.1 >= 47.0.4; transitive copy 45.0.3 < 46.0.0 (advisory lists <46.0.0 as unaffected) |
Low
| CVE / GHSA / RUSTSEC | Severity | Affected versions | Fixed | Description | Affected? |
|---|---|---|---|---|---|
| GHSA-hfr4-7c6c-48w2 / RUSTSEC-2026-0090 | Low (1.0) | <43.0.0 | 43.0.1 | Use-after-free bug after cloning wasmtime::Linker. | No — direct 49.0.1 / transitive 45.0.3 — both >= 43.0.1 |
| GHSA-6wgr-89rj-399p / RUSTSEC-2026-0088 | Low (2.3) | <43.0.1 | 43.0.1 | Data leakage between pooling allocator instances. | No — direct 49.0.1 / transitive 45.0.3 — both >= 43.0.1, and pooling allocator is not enabled |
| GHSA-m9w2-8782-2946 / RUSTSEC-2026-0086 | Low | <43.0.1 | 43.0.1 | Host data leakage with 64-bit tables and Winch. | No — direct 49.0.1 / transitive 45.0.3 — both >= 43.0.1, and Winch is not enabled |
| GHSA-hgjw-h833-99q9 / RUSTSEC-2026-0222 | Low (3.8) | <24.0.12; >=25.0.0, <36.0.13; >=37.0.0, <46.0.2; >=47.0.0, <47.0.3 | 24.0.12, 36.0.13, 46.0.2, 47.0.3 | Stores can mix up type indices between engines. | Direct copy: No — resolved 49.0.1. Transitive yara-x copy (45.0.3): Yes — ignored in deny.toml with rationale (evaluation in ADR-0040). |
| GHSA-3p27-qvp9-27qf | Low | wasmtime-wasi <46.0.0 | 46.0.0 | Leak in WASIp1 fd_renumber implementation. | No — wasmtime-wasi not in dependency tree |
| GHSA-jqpg-j7w6-42pr / RUSTSEC-2026-0316 | Low | <36.0.16; >=37.0.0, <48.0.3; >=49.0.0, <49.0.1 | 36.0.16, 48.0.3, 49.0.1 | Dynamic record lifting can allocate beyond the hostcall fuel limit. | Direct copy: No — resolved 49.0.1. Transitive yara-x copy (45.0.3): Yes — ignored in deny.toml with rationale (no patched 45.x exists — fixes are in >=36.0.16, >=48.0.3, >=49.0.1; evaluation in ADR-0040, high-severity sibling RUSTSEC-2026-0269 handled the same way). |
Historical
| CVE / GHSA / RUSTSEC | Severity | Affected versions | Fixed | Description | Affected? |
|---|---|---|---|---|---|
| CVE-2024-47763 / GHSA-q8hx-mm92-4wvg / RUSTSEC-2024-0440 | High (5.5) | <21.0.2; >=21.0.2, <22.0.0; >=22.0.1, <23.0.0; >=23.0.3, <24.0.0; >=24.0.1, <25.0.0 | 25.0.2 | Runtime crash when combining tail calls with stack traces. | No — direct 49.0.1 / transitive 45.0.3 — both >= 25.0.2 |
Exploitability assessment
Both Critical CVEs require a malicious WebAssembly guest module to be loaded and executed. The attack surface is:
- A plugin author crafts a
.wasmcomponent that exploits the Cranelift aarch64 miscompilation or the Winch backend memory access bug. - The malicious component is loaded by
arbitraitor-plugin-host. - The component executes and reads/writes host memory outside the sandbox.
Mitigating factors in the current configuration:
- The
experimental-wasmfeature is off by default. Wasmtime plugin loading is not active unless the feature is explicitly enabled at build time. - The Winch compiler backend is not enabled. Only
craneliftis in the feature set, so CVE-2026-34987 (Winch-only) is not reachable. - CVE-2026-34971 requires
wasm_memory64enabled and Spectre mitigations disabled. Wasmtime enables Spectre mitigations by default; Arbitraitor does not disable them. - The resolved versions are above the fix version for all April 2026 and August 2026 advisories (the direct copy at 49.0.1 is above all known fix versions; the yara-x transitive copy at 45.0.3 has formally-evaluated ignores for the three advisories it trips).
Enforcement
-
cargo-deny advisories check —
deny.tomlalready configures the RustSec advisory database (https://github.com/rustsec/advisory-db) andyanked = "deny". Thesecurity.ymlCI workflow runscargo deny check advisorieson every PR. Any new Wasmtime advisory published to RustSec will automatically fail CI if the pinned version is affected. -
cargo-audit — The
security.ymlCI workflow also runscargo auditas a second independent check against the RustSec database. -
GitHub dependency review — Blocks vulnerable dependency additions in PRs via GitHub’s native dependency review API.
-
Monitoring process — The risk register in this ADR must be updated whenever:
- A new Wasmtime advisory is published (check https://github.com/bytecodealliance/wasmtime/security/advisories).
- The pinned
wasmtimeversion inCargo.tomlorCargo.lockchanges. - The feature set enabled on the
wasmtimedependency changes (e.g., enabling Winch orwasm_memory64).
Consequences
- The risk register provides a single source of truth for Wasmtime CVE awareness in the Arbitraitor plugin sandbox.
cargo-denyandcargo-auditin CI automatically enforce the advisory baseline. The only Wasmtime entries in thedeny.tomlignore list (RUSTSEC-2026-0222, RUSTSEC-2026-0269, RUSTSEC-2026-0316) are scoped to the transitive yara-x-pinned copy (45.0.3) and carry recorded removal conditions (ADR-0040) — all three drop when yara-x requires a patched wasmtime; every advisory against the direct dependency copy still fails CI.- The
>=47.0.4version constraint inCargo.tomlis a security floor (ADR-0040), not a pin: it states the minimum patched version while leaving semver-compatible upgrades to dependency tooling. The lockfile resolves49.0.1for the direct dependency, which is above all known fix versions (the yara-x-pinned transitive copy remains at 45.0.3 and is covered by the ignore rationale above). Lockfile changes are security-relevant per conventions §Dependencies and must be reviewed. - If a future advisory affects
49.0.1, CI will fail on the advisories check, blocking merge until the version is bumped or the advisory is formally evaluated and ignored with justification (following the pattern used forRUSTSEC-2025-0141etc. indeny.toml). - Enabling the Winch compiler backend or
wasm_memory64in the future requires updating this risk register and re-evaluating exploitability. - The
experimental-wasmfeature gate means Wasmtime plugin loading is not active in default builds. The risk register still applies because the feature can be enabled by users building from source.
Alternatives considered
Pin a minimum version floor in Cargo.toml
Deferred at the time of this ADR (issue #463 constraints: a separate
decision requiring its own ADR and advisory check); adopted by
ADR 0040 in September 2026 after
RUSTSEC-2026-0268/0269 affected the resolved version and fresh resolves
could unify the direct copy onto yara-x’s then-required wasmtime ^43.0.2
range (yara-x 1.20.0 has since moved to ^45.0.3).
The floor is now >=47.0.4.
Add explicit ignore rules in deny.toml for wasmtime advisories
Rejected. The global cargo deny check advisories already catches affected
versions. Adding ignore rules would suppress real findings. The existing
ignore list is reserved for advisories that have been formally evaluated
and accepted (e.g., transitive bincode via yara-x).
Build a custom CI job that scrapes the GHSA page
Rejected. The RustSec advisory database is already mirrored to
~/.cargo/advisory-dbs by cargo-deny and is the canonical source for
Rust crate advisories. Building a separate scraper would duplicate
existing infrastructure and add maintenance burden.
Catalog only the two Critical CVEs from the issue
Rejected. A risk register that only lists the two CVEs named in the issue would miss the 10 other advisories published in the same April 2026 batch, several of which are Moderate severity and relevant to the component-model and Cranelift features that Arbitraitor enables. A complete catalog is necessary for informed risk decisions.
References
- Issue #463 — §41.9.1 Wasmtime April 2026 critical CVE risk register.
- ADR 0006 — Wasmtime Component Model for plugins.
- ADR 0011 — Plugin trust classification model.
- Bytecode Alliance Wasmtime Security Advisories: https://github.com/bytecodealliance/wasmtime/security/advisories
- RustSec advisory database —
wasmtimepackage: https://rustsec.org/packages/wasmtime.html - CVE-2026-34971 (NVD): https://nvd.nist.gov/vuln/detail/CVE-2026-34971
- CVE-2026-34987 (NVD): https://nvd.nist.gov/vuln/detail/CVE-2026-34987
- Bytecode Alliance blog — Wasmtime’s April 9, 2026 Security Advisories: https://bytecodealliance.org/articles/wasmtime-security-advisories
- Wasmtime RELEASES.md: https://github.com/bytecodealliance/wasmtime/blob/main/RELEASES.md
deny.toml— cargo-deny configuration (advisories, licenses, bans).crates/arbitraitor-plugin-host/Cargo.toml— Wasmtime dependency declaration and feature set.