Skip to content

Commit af100d1

Browse files
authored
doc: clarify vfs is not a sandbox
Signed-off-by: Matteo Collina <hello@matteocollina.com> PR-URL: #64143 Reviewed-By: René <contact.9a5d6388@renegade334.me.uk> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
1 parent ed33ae7 commit af100d1

2 files changed

Lines changed: 46 additions & 11 deletions

File tree

SECURITY.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,24 @@ The following are **not** vulnerabilities in Node.js:
421421
restrictions of their parent process. Passing an empty or modified `execArgv`
422422
to a worker does not grant it additional permissions.
423423

424+
#### Virtual File System (`node:vfs`)
425+
426+
The experimental [Virtual File System](https://nodejs.org/api/vfs.html)
427+
(`node:vfs`) is a virtualized file-system API for tests, fixtures, embedded
428+
assets, and application-managed storage. It is **not** a sandbox, permission
429+
system, or security boundary for untrusted code.
430+
431+
Code that can load `node:vfs`, receive a `VirtualFileSystem` instance, install a
432+
mount, choose a provider, or pass paths to VFS APIs is trusted application code.
433+
A VFS mount only redirects matching file-system calls; it does not hide or
434+
restrict access to the host file system. `RealFSProvider` root checks and
435+
read-only providers are implementation behavior, not security guarantees.
436+
437+
Reports that rely on using VFS to isolate untrusted JavaScript, native code, or
438+
user-controlled paths are not considered Node.js vulnerabilities. Use OS-level
439+
isolation, such as separate users, containers, or platform sandboxes, when a
440+
security boundary is required.
441+
424442
#### V8 Sandbox
425443

426444
The V8 sandbox is an in-process isolation mechanism internal to V8 that is not

doc/api/vfs.md

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@ added: v26.4.0
1010
1111
<!-- source_link=lib/vfs.js -->
1212

13-
The `node:vfs` module provides an in-memory virtual file system with a
14-
`node:fs`-like API. It is useful for tests, fixtures, embedded assets, and other
15-
scenarios where you need a self-contained file system without touching the
16-
actual file-system.
13+
The `node:vfs` module provides a virtual file system with a `node:fs`-like API.
14+
It is useful for tests, fixtures, embedded assets, and other scenarios where you
15+
need a self-contained file system without touching the actual file-system.
1716

1817
To access it:
1918

@@ -28,6 +27,22 @@ const vfs = require('node:vfs');
2827
This module is only available under the `node:` scheme, and only when Node.js
2928
is started with the `--experimental-vfs` flag.
3029

30+
## Security
31+
32+
The VFS API is not a sandbox, permission system, or access-control mechanism.
33+
It does not isolate untrusted code from the host file system or from other
34+
Node.js capabilities. Code that can access a [`VirtualFileSystem`][] instance,
35+
mount it, select its provider, or pass paths to it is trusted application code.
36+
37+
Mounting a VFS only redirects supported [`node:fs`][] calls whose resolved paths
38+
are under the mount point. It does not prevent code from using other paths or
39+
other Node.js APIs to access resources available to the process.
40+
[`RealFSProvider`][] maps VFS paths under its configured root and rejects paths
41+
that resolve outside that root, but that check is not a security boundary. Do
42+
not rely on VFS to run untrusted code; use operating-system-level isolation,
43+
such as separate users, containers, or platform sandboxes, when a security
44+
boundary is required.
45+
3146
## Basic usage
3247

3348
```cjs
@@ -68,7 +83,7 @@ const vfs = require('node:vfs');
6883
const memoryVfs = vfs.create();
6984

7085
// Explicit provider
71-
const realVfs = vfs.create(new vfs.RealFSProvider('/tmp/sandbox'));
86+
const realVfs = vfs.create(new vfs.RealFSProvider('/tmp/vfs-root'));
7287
```
7388

7489
## Class: `VirtualFileSystem`
@@ -257,10 +272,11 @@ myVfs.writeFileSync('/x.txt', 'fail'); // throws EROFS
257272
added: v26.4.0
258273
-->
259274

260-
A provider that wraps a directory (i.e. one on the actual file system) and exposes its
261-
contents through the VFS API. All VFS paths are resolved relative to
262-
the root and verified to stay inside it; symbolic links resolving
263-
outside the root are rejected.
275+
A provider that wraps a directory (i.e. one on the actual file system) and
276+
exposes its contents through the VFS API. All VFS paths are resolved relative to
277+
the root and verified to stay inside it; symbolic links resolving outside the
278+
root are rejected. This path mapping is not a sandbox or access-control
279+
mechanism.
264280

265281
### `new RealFSProvider(rootPath)`
266282

@@ -274,8 +290,8 @@ added: v26.4.0
274290
```cjs
275291
const vfs = require('node:vfs');
276292

277-
const realVfs = vfs.create(new vfs.RealFSProvider('/tmp/sandbox'));
278-
realVfs.writeFileSync('/file.txt', 'hello'); // writes /tmp/sandbox/file.txt
293+
const realVfs = vfs.create(new vfs.RealFSProvider('/tmp/vfs-root'));
294+
realVfs.writeFileSync('/file.txt', 'hello'); // writes /tmp/vfs-root/file.txt
279295
```
280296

281297
### `realFSProvider.rootPath`
@@ -303,6 +319,7 @@ fields use synthetic but stable values:
303319
* Times default to the moment the entry was created/last modified.
304320

305321
[`MemoryProvider`]: #class-memoryprovider
322+
[`RealFSProvider`]: #class-realfsprovider
306323
[`VirtualFileSystem`]: #class-virtualfilesystem
307324
[`VirtualProvider`]: #class-virtualprovider
308325
[`fs.BigIntStats`]: fs.md#class-fsbigintstats

0 commit comments

Comments
 (0)