{"id":"CVE-2026-47261","aliases":["GHSA-2r75-cxrj-cmph","RUSTSEC-2026-0149"],"title":"wasmtime-wasi: WASI path_open(TRUNCATE) bypasses `FilePerms::WRITE` host restriction","summary":"wasmtime-wasi: WASI path_open(TRUNCATE) bypasses `FilePerms::WRITE` host restriction","severity":"high","cvss":7.5,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N","vendor":"wasmtime-wasi","product":"wasmtime-wasi","ecosystem":"rust","affected":["wasmtime-wasi >= 37.0.0, < 44.0.2","wasmtime-wasi >= 25.0.0, < 36.0.10","wasmtime-wasi < 24.0.9"],"patched":["wasmtime-wasi 44.0.2","wasmtime-wasi 36.0.10","wasmtime-wasi 24.0.9"],"published":"2026-06-05","updated":"2026-07-08","source":"OSV","sourceUrl":"https://osv.dev/vulnerability/GHSA-2r75-cxrj-cmph","references":[{"url":"https://github.com/bytecodealliance/wasmtime/security/advisories/GHSA-2r75-cxrj-cmph"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-47261"},{"url":"https://github.com/bytecodealliance/wasmtime"},{"url":"https://github.com/bytecodealliance/wasmtime/releases/tag/v24.0.9"},{"url":"https://github.com/bytecodealliance/wasmtime/releases/tag/v36.0.10"},{"url":"https://github.com/bytecodealliance/wasmtime/releases/tag/v44.0.2"},{"url":"https://github.com/bytecodealliance/wasmtime/releases/tag/v45.0.0"},{"url":"https://rustsec.org/advisories/RUSTSEC-2026-0149.html"}],"tags":["osv","rust"],"epss":0.00357,"epssPercentile":0.2954,"ingestedAt":"2026-07-09T18:56:37.268Z","slug":"CVE-2026-47261","body":"## Overview\n\n## 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.\n\n## Affected packages\n\n- `wasmtime-wasi >= 37.0.0, < 44.0.2`\n- `wasmtime-wasi >= 25.0.0, < 36.0.10`\n- `wasmtime-wasi < 24.0.9`\n\n## Remediation\n\nUpgrade to a patched release:\n\n- `wasmtime-wasi 44.0.2`\n- `wasmtime-wasi 36.0.10`\n- `wasmtime-wasi 24.0.9`","depth":"twilight","depthScore":41,"depthScoreParts":{"impact":41.3,"likelihood":0.1,"exploitation":0,"ransomware":0},"changes":[]}