This repository showcases how to open files outside the "filesystem sandbox" in node:wasi.
The WASI
class has a preopens
parameter that describes what files the WASM program has access to. Usually, accessing files outside of it results in a "file not found" error, but it's possible to circumvent that if a symlink replaces the file at a very precise moment.
It just means that node:wasi doesn't fully implement the WASI filesystem specification
Importantly, the sandboxing is designed to be implementable even in the presence of outside processes accessing the same filesystem, including renaming, unlinking, and creating new files and directories.
-
(optional) build hello.c into hello.wasm
-
open a terminal and run
./swapper.sh
-
open another terminal and run
node main.js | grep OUTSIDE
hello.wasm is able to open ./outside.txt
$ node main.js | grep OUTSIDE
(node:426476) ExperimentalWarning: WASI is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
Data: !!!! OUTSIDE - THIS FILE SHOULD NOT BE READABLE BY HELLO.WASM
Data: !!!! OUTSIDE - THIS FILE SHOULD NOT BE READABLE BY HELLO.WASM
Data: !!!! OUTSIDE - THIS FILE SHOULD NOT BE READABLE BY HELLO.WASM
Code using WASI should be not able to open any files outside the preopens directory.
$ ln -sf ../outside.txt preopens/inside.txt
$ cat preopens/inside.txt
<contents of outside.txt ...>
$ node main.js
Error: no such file or directory
-
uvwasi__resolve_path is invoked, it sees that
preopens/inside.txt
is an actual file inside the preopens dir, so the sandbox check succeeds and the WASM program is allowed to access the file. -
The swapper script replaces
preopens/inside.txt
with a symlink tooutside.txt
-
uv_fs_open is called with
preopens/inside.txt
and opensoutside.txt
, which WASI is not supposed to allow.