{"id":"GHSA-2r75-cxrj-cmph","summary":"wasmtime-wasi: WASI path_open(TRUNCATE) bypasses `FilePerms::WRITE` host restriction","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–969:\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's `wasmtime-cli`'s use of wasmtime-wasi is not affected, because it always sets `FilePerms::all()` for all preopens.","aliases":["CVE-2026-47261","RUSTSEC-2026-0149"],"modified":"2026-09-10T03:51:07.520225710Z","published":"2026-06-05T15:47:02Z","database_specific":{"cwe_ids":["CWE-284"],"severity":"HIGH","github_reviewed":true,"github_reviewed_at":"2026-06-05T15:47:02Z","nvd_published_at":"2026-06-15T21:17:11Z"},"references":[{"type":"WEB","url":"https://github.com/bytecodealliance/wasmtime/security/advisories/GHSA-2r75-cxrj-cmph"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-47261"},{"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"}],"affected":[{"package":{"name":"wasmtime-wasi","ecosystem":"crates.io","purl":"pkg:cargo/wasmtime-wasi"},"ranges":[{"type":"SEMVER","events":[{"introduced":"37.0.0"},{"fixed":"44.0.2"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/06/GHSA-2r75-cxrj-cmph/GHSA-2r75-cxrj-cmph.json"}},{"package":{"name":"wasmtime-wasi","ecosystem":"crates.io","purl":"pkg:cargo/wasmtime-wasi"},"ranges":[{"type":"SEMVER","events":[{"introduced":"25.0.0"},{"fixed":"36.0.10"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/06/GHSA-2r75-cxrj-cmph/GHSA-2r75-cxrj-cmph.json"}},{"package":{"name":"wasmtime-wasi","ecosystem":"crates.io","purl":"pkg:cargo/wasmtime-wasi"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"24.0.9"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/06/GHSA-2r75-cxrj-cmph/GHSA-2r75-cxrj-cmph.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N"}]}