The WebAssembly (Wasm) Module Expiry Trap: Tracking Client Edge Runtimes and Binaries
As compute moves closer to users, engineering teams and agencies increasingly ship WebAssembly (Wasm) modules to edge platforms such as Cloudflare Workers, Fastly Compute and Vercel Functions on the Edge runtime. Wasm offers near-native performance on compute-heavy work, lets teams use languages like Rust, Go and C, and runs inside a sandbox. It also creates an operational blind spot: a compiled Wasm binary has no expiry date, but the things it depends on do.
A .wasm file is an opaque artifact. It is tied to the compiler toolchain that produced it, the compilation target it was built for, the system-interface version it imports, the limits of the plan it is deployed on, and sometimes the signing identity used to approve it. When any of these moves, a module that ran for months can stop building, stop deploying or stop instantiating. Nothing in the binary itself warns you.
1. Anatomy of the Edge Wasm Lifecycle
Edge platforms remove server maintenance, but they move that complexity into the build pipeline and the artifact lifecycle.
[Source Code (Rust / Go / C)]
│
▼ Compiler toolchain + compilation target
[Wasm Binary (.wasm)]
│
▼ Optional: signing / attestation (your policy)
[Bundle or package uploaded to the platform]
│
▼ Edge runtime (e.g. workerd, a Wasmtime-based host)
[Client execution]
The three major platforms handle Wasm differently:
| Platform | How Wasm is delivered | Detail worth tracking |
| --- | --- | --- |
| Cloudflare Workers | A .wasm file is imported into the Worker and instantiated with WebAssembly.instantiate(). Wrangler bundles any module ending in .wasm or .wasm?module. | Worker size is capped at 3 MB (Free) or 10 MB (Paid) after gzip, with a 1-second startup limit. |
| Fastly Compute | A package built by the Fastly CLI from your project, using the toolchain pinned in rust-toolchain.toml for Rust. | Fastly validates Rust versions against its SDK before supporting them. |
| Vercel Functions | Wasm works with the edge, nodejs and bun runtimes. | On the Edge runtime, WebAssembly.instantiate requires the Wasm source to come from an import statement. |
Cloudflare’s limits page also lists 64 MB as the pre-compression bundle limit and notes that larger bundles can slow startup. The Wasm module ships inside the deployment, so a plan or bundle-size change can break a client’s Worker even if no code changed.
2. The Silent Vectors of Failure
Vector 1: Toolchain and target drift
Compilation targets get renamed and removed, and compiler releases occasionally produce bad output for a given platform. Real examples:
- The WASI target rename. Rust 1.78 (May 2024) introduced wasm32-wasip1 as a rename of wasm32-wasi. Rust 1.84 (January 2025) removed the old target entirely, so projects still referencing wasm32-wasi failed after upgrading the compiler.
- Fastly’s CLI target. Fastly’s Rust guide says CLI 11.0.0 and later supports only the wasm32-wasip1 target for Rust services, which requires Rust 1.78.0 or higher.
- A compiler release that produced broken packages. Fastly’s Rust guide states that Rust 1.91.0 is not compatible with Compute and that 1.91.1 fixed the problem. The Fastly CLI was also updated to refuse builds with 1.91.0. Fastly’s engineering team had confirmed those packages would crash when handling incoming requests.
The last case shows the risk of floating toolchains. A pipeline that tracks the stable channel can pick up a compiler release the platform has not validated, and the failure appears at runtime rather than at build time. Fastly’s own guidance is to avoid updating Rust until Fastly releases an SDK that supports the new version.
Vector 2: WASI and runtime version drift
The system interface that Wasm modules import is still evolving, so modules built against older interface versions need deliberate migration.
- WASI 0.3.0 was released on June 11, 2026. It moves async support into the Component Model itself, using built-in stream, future and async func primitives. The wasi:io package, which WASI 0.2 used for async, is replaced by these primitives.
- Runtimes follow on their own schedules. The WASI project said Wasmtime 46 would ship WASI 0.3.0 with Component Model async enabled by default. The Wasmtime 46.0.0 release notes confirm that WASI 0.3.0 support and the component-model-async feature are enabled by default, and the release landed on June 22, 2026.
- Not every host moves at the same time. Your edge platform’s runtime version, your local test runtime and your toolchain’s WASI target can each be on different interface versions.
Cloudflare mitigates part of this with compatibility dates. Its open-source workerd runtime is versioned by date, and the README states that updating workerd will never break your JavaScript code because Workers can pin to an older compatibility date. That promise covers the JavaScript API surface. It does not cover whether your Wasm module’s own imports still match what you built it against, so you still need to test the module itself.
Also note that Fastly’s original runtime, Lucet, reached end-of-life and was archived in March 2022. Its maintainers directed users to Wasmtime, which absorbed Lucet’s features. Documentation or blog posts that still refer to Lucet as a current edge runtime are out of date.
Vector 3: Signing identities and embedded time-limited material
None of the platform documentation reviewed for this article describes mandatory signature checks on uploaded Wasm modules. Signing is usually a policy your own team or a client’s security team adds to the pipeline. Where it exists, it creates its own expiry risk:
- Module signatures are a proposal, not a universal standard. The WebAssembly module signatures proposal embeds signatures in the module so a runtime or deploy gate can verify them before instantiation. wasmsign2 is a reference implementation.
- Keyless signing changes what “expired” means. Sigstore’s public Fulcio service issues short-lived certificates valid for 10 minutes, so verification has to prove the artifact was signed while the certificate was valid, using a timestamp or transparency-log entry, rather than checking whether the certificate is valid now. A verification step that checks the certificate’s validity at deploy time will reject every keyless-signed artifact.
- Key-based signing carries a rotation burden. If your pipeline signs with a long-lived key or certificate and the deploy gate verifies it, an expired or rotated key will block deployments until the pipeline and the gate agree again.
- Embedded time-limited material is a self-inflicted trap. If a build embeds an evaluation license or a time-limited credential, the module works until that timestamp passes. Platform documentation does not describe this behavior. It is a design choice, and it is easy to forget when a client engagement ends.
Vector 4: Plan tiers, size limits and startup budgets
Limits can change what a deployment is allowed to do. Cloudflare’s published limits differ between Free and Paid plans for Worker size (3 MB vs. 10 MB compressed), and both plans allow 1 second of startup time. A Wasm module that grew past the Free-plan cap, or a client account moved between plans, can produce a failed deployment that has nothing to do with your code. Separately, Workers that exceed their CPU time limit return Cloudflare’s Error 1102, which is easy to mistake for a runtime bug if you are not watching resource limits.
3. Best Practices for Mitigating Edge Wasm Drift
- Pin compiler toolchains and targets. Avoid stable or latest in compilation stages. Commit a rust-toolchain.toml that names both the exact compiler version and the target:
[toolchain]
channel = "<version validated for your platform's SDK>"
targets = ["wasm32-wasip1"]
Upgrade deliberately, after the platform vendor says the new version is supported.
- Read release notes for your target and your runtime. Target renames (wasm32-wasi to wasm32-wasip1) and interface changes (WASI 0.2 to 0.3) are announced well in advance. Put the dates in your team’s calendar.
- Run synthetic probes against deployed modules. Exercise a cold-start path for each deployed module on a schedule, so a broken package or failed instantiation shows up in your monitoring before a client reports it.
- Keep artifacts in a registry with metadata. Store each build with its compiler version, target, WASI version, build date, size and the signing identity used. Cosign can store and sign Wasm modules as OCI artifacts, which gives you a versioned, verifiable record.
- Make signature verification time-aware. If you use keyless signing, verify against the signing time evidenced by the transparency log or a timestamp authority rather than the current time. If you use long-lived keys, track their expiry dates like any other certificate.
- Canary and roll back. Route a small share of traffic to newly compiled modules, and keep the previous known-good build deployable so a link or instantiation failure can be reversed quickly.
- Record limits and plan tier per client. Note the Worker size, startup time and plan tier against each client deployment, and re-check them when the client’s account changes.
An inventory template for client edge deployments
For each client edge deployment, record:
| Field | Why it matters |
| --- | --- |
| Platform and plan tier | Size and startup limits differ by plan. |
| Compiler version and target | Detects drift such as wasm32-wasi removal or an unvalidated Rust release. |
| WASI version and runtime version | Detects interface mismatches such as WASI 0.2 vs. 0.3. |
| Compatibility date (Cloudflare) | Shows which runtime behavior the Worker is pinned to. |
| Signing method and key/certificate expiry | Prevents deploy-gate failures. |
| Account owner and billing contact | Ensures someone can act when the platform plan changes. |
| Last successful cold-start probe | Shows when the module was last confirmed working. |
4. Conclusion
WebAssembly at the edge delivers real speed and language flexibility, but a compiled module is not a write-once file. It depends on a compiler version, a compilation target, a system-interface version, a platform’s limits and, where you use it, a signing identity. Each of these has changed within the last two years, and several changes broke previously working builds. Teams that treat Wasm modules as living components, with pinned toolchains, recorded metadata and regular health probes, can avoid most of these failures and diagnose the rest faster.
Further Reading
- Cloudflare Workers: Wasm in JavaScript
- Cloudflare Workers limits
- Fastly: Rust on the Compute platform
- Vercel: Using WebAssembly (Wasm)
- WASI 0.3 release notes (wasi.dev)
- Wasmtime 46.0.0 release notes
- Rust: removal of the wasm32-wasi target
- WebAssembly module signatures proposal
---
Originally published at instarenewal.com
Wasmtime fixed a critical sandbox escape bug (CVSS 9.3)
Not sure if Rustaceans in this sub saw this news earlier this month. But given AI agents are getting very good at escaping sandboxes now, it might be worth your attention to patch Wasmtime.
TL;DR: A typo in a validation check let a malicious WebAssembly guest pass an invalid callback signature, overflow the host’s native stack by up to 16KB, and potentially run arbitrary code on the host. Fixed in Wasmtime 48.0.4 and 49.0.2.
Wasmtime is a WebAssembly runtime written in Rust, built by the Bytecode Alliance (Fastly, Mozilla and others are members). It runs WebAssembly modules and components outside the browser, often as a sandbox for untrusted code.
Wasmtime published a critical security advisory on 2 October, GHSA-32h6-97mm-8q3c, CVSS 9.3. The bug sat in the component model’s handling of async callbacks.
Three checks were missing or wrong:
- The validator in wasmparser (crates/wasmparser/src/validator/component.rs) checked a callback’s signature with this line: if func_ty.params() != [ValType::I32; 3] && func_ty.params() != [ValType::I32] { It used && instead of ||, and it checked params() twice instead of checking results() at all. A callback only failed validation if it matched neither shape, so the result type was never checked.
- Wasmtime recorded the callback’s index without checking its arity or return type itself, trusting the validator to have done it. The host-to-guest trampoline had no bounds check on its parameter and result buffer either.
- The stack space reserved for the callback’s return value was sized for the expected arity, not the actual one.
A guest module can supply a callback with an invalid return type that still passes validation. Wasmtime then writes up to about 16KB of guest-controlled data onto the host’s native stack, which can overwrite a return address.
Vulnerable versions: wasmtime 39.0.0 up to 48.0.4, and 49.0.0 up to 49.0.2. Fixed in 48.0.4 and 49.0.2. A workaround is to disable component-model-async, or to validate components with wasmparser 1.260.0 or later before passing them to Wasmtime.
Link to the original source - github.com/bytecodealliance/wasmtime/security/adv…
131 points · 9 comments
Mentions
i can't believe how fast it is, too see: wasmtime#2566
6/10 Wasmtime keeps maturing as a fast, secure, standards-compliant Wasm runtime. Still my pick for sandboxed portable compute on the server and edge. bytecodealliance/wasmtime
The WebAssembly (Wasm) Module Expiry Trap: Tracking Client Edge Runtimes and Binaries As compute moves closer to users, engineering teams and agencies increasingly ship WebAssembly (Wasm) modules to edge platforms such as Cloudflare Workers, Fastly Compute and Vercel Functions on the Edge runtime. Wasm offers near-native performance on compute-heavy work, lets teams use languages like Rust, Go and C, and runs inside a sandbox. It also creates an operational blind spot: a compiled Wasm binary has no expiry date, but the things it depends on do. A .wasm file is an opaque artifact. It is tied to the compiler toolchain that produced it, the compilation target it was built for, the system-interface version it imports, the limits of the plan it is deployed on, and sometimes the signing identity used to approve it. When any of these moves, a module that ran for months can stop building, stop deploying or stop instantiating. Nothing in the binary itself warns you. 1. Anatomy of the Edge Wasm Lifecycle Edge platforms remove server maintenance, but they move that complexity into the build pipeline and the artifact lifecycle. [Source Code (Rust / Go / C)] │ ▼ Compiler toolchain + compilation target [Wasm Binary (.wasm)] │ ▼ Optional: signing / attestation (your policy) [Bundle or package uploaded to the platform] │ ▼ Edge runtime (e.g. workerd, a Wasmtime-based host) [Client execution] The three major platforms handle Wasm differently: | Platform | How Wasm is delivered | Detail worth tracking | | --- | --- | --- | | Cloudflare Workers | A .wasm file is imported into the Worker and instantiated with WebAssembly.instantiate(). Wrangler bundles any module ending in .wasm or .wasm?module. | Worker size is capped at 3 MB (Free) or 10 MB (Paid) after gzip, with a 1-second startup limit. | | Fastly Compute | A package built by the Fastly CLI from your project, using the toolchain pinned in rust-toolchain.toml for Rust. | Fastly validates Rust versions against its SDK before supporting them. | | Vercel Functions | Wasm works with the edge, nodejs and bun runtimes. | On the Edge runtime, WebAssembly.instantiate requires the Wasm source to come from an import statement. | Cloudflare’s limits page also lists 64 MB as the pre-compression bundle limit and notes that larger bundles can slow startup. The Wasm module ships inside the deployment, so a plan or bundle-size change can break a client’s Worker even if no code changed. 2. The Silent Vectors of Failure Vector 1: Toolchain and target drift Compilation targets get renamed and removed, and compiler releases occasionally produce bad output for a given platform. Real examples: - The WASI target rename. Rust 1.78 (May 2024) introduced wasm32-wasip1 as a rename of wasm32-wasi. Rust 1.84 (January 2025) removed the old target entirely, so projects still referencing wasm32-wasi failed after upgrading the compiler. - Fastly’s CLI target. Fastly’s Rust guide says CLI 11.0.0 and later supports only the wasm32-wasip1 target for Rust services, which requires Rust 1.78.0 or higher. - A compiler release that produced broken packages. Fastly’s Rust guide states that Rust 1.91.0 is not compatible with Compute and that 1.91.1 fixed the problem. The Fastly CLI was also updated to refuse builds with 1.91.0. Fastly’s engineering team had confirmed those packages would crash when handling incoming requests. The last case shows the risk of floating toolchains. A pipeline that tracks the stable channel can pick up a compiler release the platform has not validated, and the failure appears at runtime rather than at build time. Fastly’s own guidance is to avoid updating Rust until Fastly releases an SDK that supports the new version. Vector 2: WASI and runtime version drift The system interface that Wasm modules import is still evolving, so modules built against older interface versions need deliberate migration. - WASI 0.3.0 was released on June 11, 2026. It moves async support into the Component Model itself, using built-in stream, future and async func primitives. The wasi:io package, which WASI 0.2 used for async, is replaced by these primitives. - Runtimes follow on their own schedules. The WASI project said Wasmtime 46 would ship WASI 0.3.0 with Component Model async enabled by default. The Wasmtime 46.0.0 release notes confirm that WASI 0.3.0 support and the component-model-async feature are enabled by default, and the release landed on June 22, 2026. - Not every host moves at the same time. Your edge platform’s runtime version, your local test runtime and your toolchain’s WASI target can each be on different interface versions. Cloudflare mitigates part of this with compatibility dates. Its open-source workerd runtime is versioned by date, and the README states that updating workerd will never break your JavaScript code because Workers can pin to an older compatibility date. That promise covers the JavaScript API surface. It does not cover whether your Wasm module’s own imports still match what you built it against, so you still need to test the module itself. Also note that Fastly’s original runtime, Lucet, reached end-of-life and was archived in March 2022. Its maintainers directed users to Wasmtime, which absorbed Lucet’s features. Documentation or blog posts that still refer to Lucet as a current edge runtime are out of date. Vector 3: Signing identities and embedded time-limited material None of the platform documentation reviewed for this article describes mandatory signature checks on uploaded Wasm modules. Signing is usually a policy your own team or a client’s security team adds to the pipeline. Where it exists, it creates its own expiry risk: - Module signatures are a proposal, not a universal standard. The WebAssembly module signatures proposal embeds signatures in the module so a runtime or deploy gate can verify them before instantiation. wasmsign2 is a reference implementation. - Keyless signing changes what “expired” means. Sigstore’s public Fulcio service issues short-lived certificates valid for 10 minutes, so verification has to prove the artifact was signed while the certificate was valid, using a timestamp or transparency-log entry, rather than checking whether the certificate is valid now. A verification step that checks the certificate’s validity at deploy time will reject every keyless-signed artifact. - Key-based signing carries a rotation burden. If your pipeline signs with a long-lived key or certificate and the deploy gate verifies it, an expired or rotated key will block deployments until the pipeline and the gate agree again. - Embedded time-limited material is a self-inflicted trap. If a build embeds an evaluation license or a time-limited credential, the module works until that timestamp passes. Platform documentation does not describe this behavior. It is a design choice, and it is easy to forget when a client engagement ends. Vector 4: Plan tiers, size limits and startup budgets Limits can change what a deployment is allowed to do. Cloudflare’s published limits differ between Free and Paid plans for Worker size (3 MB vs. 10 MB compressed), and both plans allow 1 second of startup time. A Wasm module that grew past the Free-plan cap, or a client account moved between plans, can produce a failed deployment that has nothing to do with your code. Separately, Workers that exceed their CPU time limit return Cloudflare’s Error 1102, which is easy to mistake for a runtime bug if you are not watching resource limits. 3. Best Practices for Mitigating Edge Wasm Drift - Pin compiler toolchains and targets. Avoid stable or latest in compilation stages. Commit a rust-toolchain.toml that names both the exact compiler version and the target: [toolchain] channel = "<version validated for your platform's SDK>" targets = ["wasm32-wasip1"] Upgrade deliberately, after the platform vendor says the new version is supported. - Read release notes for your target and your runtime. Target renames (wasm32-wasi to wasm32-wasip1) and interface changes (WASI 0.2 to 0.3) are announced well in advance. Put the dates in your team’s calendar. - Run synthetic probes against deployed modules. Exercise a cold-start path for each deployed module on a schedule, so a broken package or failed instantiation shows up in your monitoring before a client reports it. - Keep artifacts in a registry with metadata. Store each build with its compiler version, target, WASI version, build date, size and the signing identity used. Cosign can store and sign Wasm modules as OCI artifacts, which gives you a versioned, verifiable record. - Make signature verification time-aware. If you use keyless signing, verify against the signing time evidenced by the transparency log or a timestamp authority rather than the current time. If you use long-lived keys, track their expiry dates like any other certificate. - Canary and roll back. Route a small share of traffic to newly compiled modules, and keep the previous known-good build deployable so a link or instantiation failure can be reversed quickly. - Record limits and plan tier per client. Note the Worker size, startup time and plan tier against each client deployment, and re-check them when the client’s account changes. An inventory template for client edge deployments For each client edge deployment, record: | Field | Why it matters | | --- | --- | | Platform and plan tier | Size and startup limits differ by plan. | | Compiler version and target | Detects drift such as wasm32-wasi removal or an unvalidated Rust release. | | WASI version and runtime version | Detects interface mismatches such as WASI 0.2 vs. 0.3. | | Compatibility date (Cloudflare) | Shows which runtime behavior the Worker is pinned to. | | Signing method and key/certificate expiry | Prevents deploy-gate failures. | | Account owner and billing contact | Ensures someone can act when the platform plan changes. | | Last successful cold-start probe | Shows when the module was last confirmed working. | 4. Conclusion WebAssembly at the edge delivers real speed and language flexibility, but a compiled module is not a write-once file. It depends on a compiler version, a compilation target, a system-interface version, a platform’s limits and, where you use it, a signing identity. Each of these has changed within the last two years, and several changes broke previously working builds. Teams that treat Wasm modules as living components, with pinned toolchains, recorded metadata and regular health probes, can avoid most of these failures and diagnose the rest faster. Further Reading - Cloudflare Workers: Wasm in JavaScript - Cloudflare Workers limits - Fastly: Rust on the Compute platform - Vercel: Using WebAssembly (Wasm) - WASI 0.3 release notes (wasi.dev) - Wasmtime 46.0.0 release notes - Rust: removal of the wasm32-wasi target - WebAssembly module signatures proposal --- Originally published at instarenewal.com
🚨 Two critical Wasmtime flaws could allow malicious WebAssembly modules to escape the runtime sandbox Both vulnerabilities affect Cranelift, Wasmtime’s default compiler, and carry CVSS scores of 9.9. ⠀ CVE-2026-115889 affects all processor architectures and can trigger silent compiler errors that generate incorrect machine code. CVE-2026-115893 affects ARM64 systems and can cause large br_table instructions to jump to the wrong code location. ⠀ Exploitation requires a vulnerable Wasmtime instance to compile an attacker-controlled WebAssembly module. Services that accept and execute untrusted customer modules face the greatest risk. Fixed versions: • Wasmtime 36.0.19 • Wasmtime 48.0.7 • Wasmtime 49.0.4 • Wasmtime 50.0.0 or later No exploitation in the wild has been reported. Sources: github.com/bytecodealliance/wasmtime/security/adv… github.com/bytecodealliance/wasmtime/security/adv…
Wasmtime turi dvi kritines spragas, leidžiančias ištrūkti iš smėlio dėžės Bytecode Alliance paskelbė dvi kritines Wasmtime spragas (CVSS 9.9). Abi yra Cranelift kompiliatoriuje. Piktavališkas WebAssembly modulis gali ištrūkti iš smėlio dėžės. CVE-2026-115889 veikia visose architektūrose. CVE-2026-115893 veikia tik ARM64. Didžiausia rizika paslaugoms, kurios vykdo svetimus modulius. Išnaudojimo atvejų kol kas nepranešta. Praktinė rekomendacija. Įdiekite atnaujinimus 36.0.19, 48.0.7, 49.0.4 arba 50.0.0. Programas, į kurias įterptas Wasmtime, perkompiliuokite su nauja versija. Šaltinis (Bytecode Alliance) github.com/bytecodealliance/wasmtime/security/adv…
🤖 Wasmtime: two CVSS 9.9 Cranelift flaws let a crafted Wasm module escape the sandbox. CVE-2026-115889 (SSA index bit-packing overflow → miscompilation) and CVE-2026-115893 (aarch64 br_table). Patched in 36.0.19 / 43.0.0. github.com/bytecodealliance/wasmtime/security/adv…
🚨 2 critical Wasmtime sandbox escapes (CVSS 3.1: 9.9, CNA) ⚠️ CVE-2026-115893: aarch64 bad jump via huge br_table, since 2020 ⚠️ CVE-2026-115889: Cranelift overflow, any arch, pre-v43 ✅ Upgrade: 36.0.19 / 48.0.7 / 49.0.4 🔗 github.com/bytecodealliance/wasmtime/security/adv… #WebAssembly #AppSec t.co
Two Critical Wasmtime Vulnerabilities (CVSS 9.9) Could Allow WebAssembly Sandbox Escapes Two newly disclosed vulnerabilities in Wasmtime's Cranelift compiler could allow specially crafted WebAssembly (Wasm) modules to break out of their sandbox and potentially execute unauthorized operations on the host system. CVE-2026-115889: An integer overflow in Cranelift's internal value indexing can trigger type confusion and arbitrary miscompilation. Affects multiple architectures. CVE-2026-115893: An ARM64-specific flaw involving incorrectly compiled branch tables could redirect execution to unintended code. The underlying issue dates back to 2020. Both vulnerabilities carry a CVSS score of 9.9 (Critical). Mitigation: Update Wasmtime to a patched release. Applications embedding vulnerable Wasmtime versions may need to be rebuilt and redeployed, as updating a system-wide installation alone may not protect them. Source: github.com/bytecodealliance/wasmtime/security/adv… github.com/bytecodealliance/wasmtime/security/adv…
Wasmtime's Cranelift backend packed SSA value indices into too few bits. A huge or crafted Wasm function overflows them silently in release builds, miscompiles, and can escape the sandbox. Default config is affected. Upgrade to 43.0.0, or 36.0.19 on 36.x. github.com/bytecodealliance/wasmtime/security/adv…
Wasmtime fixed a critical sandbox escape bug (CVSS 9.3) Not sure if Rustaceans in this sub saw this news earlier this month. But given AI agents are getting very good at escaping sandboxes now, it might be worth your attention to patch Wasmtime. TL;DR: A typo in a validation check let a malicious WebAssembly guest pass an invalid callback signature, overflow the host’s native stack by up to 16KB, and potentially run arbitrary code on the host. Fixed in Wasmtime 48.0.4 and 49.0.2. Wasmtime is a WebAssembly runtime written in Rust, built by the Bytecode Alliance (Fastly, Mozilla and others are members). It runs WebAssembly modules and components outside the browser, often as a sandbox for untrusted code. Wasmtime published a critical security advisory on 2 October, GHSA-32h6-97mm-8q3c, CVSS 9.3. The bug sat in the component model’s handling of async callbacks. Three checks were missing or wrong: - The validator in wasmparser (crates/wasmparser/src/validator/component.rs) checked a callback’s signature with this line: if func_ty.params() != [ValType::I32; 3] && func_ty.params() != [ValType::I32] { It used && instead of ||, and it checked params() twice instead of checking results() at all. A callback only failed validation if it matched neither shape, so the result type was never checked. - Wasmtime recorded the callback’s index without checking its arity or return type itself, trusting the validator to have done it. The host-to-guest trampoline had no bounds check on its parameter and result buffer either. - The stack space reserved for the callback’s return value was sized for the expected arity, not the actual one. A guest module can supply a callback with an invalid return type that still passes validation. Wasmtime then writes up to about 16KB of guest-controlled data onto the host’s native stack, which can overwrite a return address. Vulnerable versions: wasmtime 39.0.0 up to 48.0.4, and 49.0.0 up to 49.0.2. Fixed in 48.0.4 and 49.0.2. A workaround is to disable component-model-async, or to validate components with wasmparser 1.260.0 or later before passing them to Wasmtime. Link to the original source - github.com/bytecodealliance/wasmtime/security/adv…