## Summary 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: ```rust dir_descriptor.open_at( PathFlags::empty(), FILENAME, OpenFlags::TRUNCATE, DescriptorFlags::READ, ) ``` ```rust 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: ```rust if oflags.contains(OpenFlags::TRUNCATE) { opts.truncate(true).write(true); } ``` and the single line fix is: ```rust 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`: ```rust 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.
## Summary 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: ```rust dir_descriptor.open_at( PathFlags::empty(), FILENAME, OpenFlags::TRUNCATE, DescriptorFlags::READ, ) ``` ```rust 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: ```rust if oflags.contains(OpenFlags::TRUNCATE) { opts.truncate(true).write(true); } ``` and the single line fix is: ```rust 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`: ```rust 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.
Update wasmtime-wasi to 44.0.2; wasmtime-wasi to 36.0.10; wasmtime-wasi to 24.0.9 if you use the affected versions. Test the change in a non-production environment first.
Local check
hol-guard supply-chain scanwasmtime-wasi: WASI path_open(TRUNCATE) bypasses `FilePerms::WRITE` host restriction affects wasmtime-wasi (rust), wasmtime-wasi (rust), wasmtime-wasi (rust). Severity is high. ## Summary 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: ```rust dir_descriptor.open_at( PathFlags::empty(), FILENAME, OpenFlags::TRUNCATE, DescriptorFlags::READ, ) ``` ```rust 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: ```rust if oflags.contains(OpenFlags::TRUNCATE) { opts.truncate(true).write(true); } ``` and the single line fix is: ```rust 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`: ```rust 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.
AI coding agents often install or upgrade packages automatically in rust. A high vulnerability in a dependency can be pulled into a project through a normal install or update without a human reviewing the change, expanding the blast radius from a single package to every agent workspace that depends on it.
| Package | Affected range | Fixed version |
|---|---|---|
| wasmtime-wasirust | >=37.0.0,<44.0.2 | 44.0.2 |
| wasmtime-wasirust | >=25.0.0,<36.0.10 | 36.0.10 |
| wasmtime-wasirust | <24.0.9 | 24.0.9 |
Fixed versions are reported by the source feed; confirm compatibility before updating.
Reported by GitHub Security Advisories (ghsa).
HOL Guard can help your team review package activity against supported protection paths.
Explore HOL GuardUpdate wasmtime-wasi to 44.0.2; wasmtime-wasi to 36.0.10; wasmtime-wasi to 24.0.9 if you use the affected versions. Test the change in a non-production environment first.
Local check
hol-guard supply-chain scanwasmtime-wasi: WASI path_open(TRUNCATE) bypasses `FilePerms::WRITE` host restriction affects wasmtime-wasi (rust), wasmtime-wasi (rust), wasmtime-wasi (rust). Severity is high. ## Summary 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: ```rust dir_descriptor.open_at( PathFlags::empty(), FILENAME, OpenFlags::TRUNCATE, DescriptorFlags::READ, ) ``` ```rust 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: ```rust if oflags.contains(OpenFlags::TRUNCATE) { opts.truncate(true).write(true); } ``` and the single line fix is: ```rust 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`: ```rust 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.
AI coding agents often install or upgrade packages automatically in rust. A high vulnerability in a dependency can be pulled into a project through a normal install or update without a human reviewing the change, expanding the blast radius from a single package to every agent workspace that depends on it.
| Package | Affected range | Fixed version |
|---|---|---|
| wasmtime-wasirust | >=37.0.0,<44.0.2 | 44.0.2 |
| wasmtime-wasirust | >=25.0.0,<36.0.10 | 36.0.10 |
| wasmtime-wasirust | <24.0.9 | 24.0.9 |
Fixed versions are reported by the source feed; confirm compatibility before updating.
Reported by GitHub Security Advisories (ghsa).
HOL Guard can help your team review package activity against supported protection paths.
Explore HOL Guard