GHSA-2R75-CXRJ-CMPH
Vulnerability from github – Published: 2026-06-05 15:47 – Updated: 2026-06-05 15:47Summary
In wasmtime-wasi, when a filesystem preopen is given DirPerms::all() and FilePerms::READ without FilePerms::WRITE, this wasmtime-wasi enforced access control mechanism can be bypassed by using the wasip2 descriptor.open-at or wasip1 path_open interfaces by opening a file with OpenFlags::TRUNCATE oflag only, for example:
dir_descriptor.open_at(
PathFlags::empty(),
FILENAME,
OpenFlags::TRUNCATE,
DescriptorFlags::READ,
)
wasip1::path_open(
dir_fd,
0,
FILENAME,
wasip1::OFLAGS_TRUNC,
wasip1::RIGHTS_FD_READ,
0,
0
)
The root cause is that the clause that considered OpenFlags::TRUNCATE did not set open_mode |= OpenMode::WRITE;, used later in that function for the access control check against FilePerms for whether opening that file is permitted. With the bug corrected, these calls to open-at and path_open fail with error-code.not-permitted and ERRNO_PERM respectively.
The bug in crates/wasi/src/filesystem.rs, Dir::open_at, lines 967–969:
if oflags.contains(OpenFlags::TRUNCATE) {
opts.truncate(true).write(true);
}
and the single line fix is:
if oflags.contains(OpenFlags::TRUNCATE) {
opts.truncate(true).write(true);
open_mode |= OpenMode::WRITE;
}
Only wasmtime-wasi embeddings that use a combination of DirPerms::MUTATE with FilePerms::READ are affected by this bug, e.g. those that use in the WasiCtxBuilder:
builder.preopened_dir("readonly", "readonly", DirPerms::READ | DirPerms::MUTATE, FilePerms::READ);
In particular, the Wasmtime project's wasmtime-cli's use of wasmtime-wasi is not affected, because it always sets FilePerms::all() for all preopens.
{
"affected": [
{
"package": {
"ecosystem": "crates.io",
"name": "wasmtime-wasi"
},
"ranges": [
{
"events": [
{
"introduced": "37.0.0"
},
{
"fixed": "44.0.2"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "crates.io",
"name": "wasmtime-wasi"
},
"ranges": [
{
"events": [
{
"introduced": "25.0.0"
},
{
"fixed": "36.0.10"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "crates.io",
"name": "wasmtime-wasi"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "24.0.9"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-47261"
],
"database_specific": {
"cwe_ids": [
"CWE-284"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-05T15:47:02Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "## Summary\n\nIn `wasmtime-wasi`, when a filesystem preopen is given `DirPerms::all()` and `FilePerms::READ` without `FilePerms::WRITE`, this wasmtime-wasi enforced access control mechanism can be bypassed by using the wasip2 `descriptor.open-at` or wasip1 `path_open` interfaces by opening a file with `OpenFlags::TRUNCATE` oflag only, for example:\n\n```rust\ndir_descriptor.open_at(\n PathFlags::empty(),\n FILENAME,\n OpenFlags::TRUNCATE,\n DescriptorFlags::READ,\n)\n```\n\n```rust\nwasip1::path_open(\n dir_fd,\n 0,\n FILENAME,\n wasip1::OFLAGS_TRUNC,\n wasip1::RIGHTS_FD_READ,\n 0,\n 0\n)\n```\n\nThe root cause is that the clause that considered `OpenFlags::TRUNCATE` did not set `open_mode |= OpenMode::WRITE;`, used later in that function for the access control check against `FilePerms` for whether opening that file is permitted. With the bug corrected, these calls to `open-at` and `path_open` fail with `error-code.not-permitted` and `ERRNO_PERM` respectively.\n\nThe bug in `crates/wasi/src/filesystem.rs`, `Dir::open_at`, lines 967\u2013969:\n\n```rust\nif oflags.contains(OpenFlags::TRUNCATE) {\n opts.truncate(true).write(true);\n}\n```\nand the single line fix is:\n```rust\nif oflags.contains(OpenFlags::TRUNCATE) {\n opts.truncate(true).write(true);\n open_mode |= OpenMode::WRITE;\n}\n```\n\nOnly wasmtime-wasi embeddings that use a combination of DirPerms::MUTATE with FilePerms::READ are affected by this bug, e.g. those that use in the `WasiCtxBuilder`:\n```rust\nbuilder.preopened_dir(\"readonly\", \"readonly\", DirPerms::READ | DirPerms::MUTATE, FilePerms::READ);\n```\n\nIn particular, the Wasmtime project\u0027s `wasmtime-cli`\u0027s use of wasmtime-wasi is not affected, because it always sets `FilePerms::all()` for all preopens.",
"id": "GHSA-2r75-cxrj-cmph",
"modified": "2026-06-05T15:47:02Z",
"published": "2026-06-05T15:47:02Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/bytecodealliance/wasmtime/security/advisories/GHSA-2r75-cxrj-cmph"
},
{
"type": "PACKAGE",
"url": "https://github.com/bytecodealliance/wasmtime"
},
{
"type": "WEB",
"url": "https://github.com/bytecodealliance/wasmtime/releases/tag/v24.0.9"
},
{
"type": "WEB",
"url": "https://github.com/bytecodealliance/wasmtime/releases/tag/v36.0.10"
},
{
"type": "WEB",
"url": "https://github.com/bytecodealliance/wasmtime/releases/tag/v44.0.2"
},
{
"type": "WEB",
"url": "https://github.com/bytecodealliance/wasmtime/releases/tag/v45.0.0"
},
{
"type": "WEB",
"url": "https://rustsec.org/advisories/RUSTSEC-2026-0149.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "wasmtime-wasi: WASI path_open(TRUNCATE) bypasses `FilePerms::WRITE` host restriction"
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.