Skip to content

fix(scripting-node): allow opt-in absolute-path filesystem reads#3981

Open
Osheun wants to merge 1 commit into
citizenfx:masterfrom
Osheun:fix/node-sandbox-absolute-read-permission
Open

fix(scripting-node): allow opt-in absolute-path filesystem reads#3981
Osheun wants to merge 1 commit into
citizenfx:masterfrom
Osheun:fix/node-sandbox-absolute-read-permission

Conversation

@Osheun
Copy link
Copy Markdown

@Osheun Osheun commented May 12, 2026

Goal of this PR

Fix #3978.

The Node.js scripting sandbox blocks every fs.read on an absolute path that is not inside a registered VFS device. This is the correct default, but it makes the MongoDB Node driver (and Mongoose) crash at construction time, because its internal getContainerMetadata() probes paths like /.dockerenv, /proc/self/cgroup, /etc/os-release to detect its runtime environment. Right now any resource using mongodb or mongoose throws Error: Access to this API has been restricted and dies before it can connect.

How is this PR achieving the goal

Adds an admin opt-in allow-list for absolute reads, mirroring the existing add_unsafe_worker_permission / add_unsafe_child_process_permission pattern:

  • New fx::ScriptingFilesystemAllowAbsoluteRead(absolutePath, resource) helper in citizen-scripting-core.
  • New console command add_unsafe_filesystem_absolute_read_permission <resource> <absolute-path>, gated by the same g_permissionModifyAllowed startup-only flag as the other _unsafe_* commands. Path must be absolute, exact-or-directory-prefix match (no glob, no traversal).
  • NodePermissionCallback consults the allow-list only for kFileSystemRead, only when no VFS device matches, and only after the existing .. traversal guard. Writes are untouched.
  • Default behaviour is unchanged: without an explicit add_unsafe_filesystem_absolute_read_permission entry, the sandbox blocks as before.

Admins write in server.cfg:

add_unsafe_filesystem_absolute_read_permission my_mongo_resource "C:\.dockerenv"
add_unsafe_filesystem_absolute_read_permission my_mongo_resource /proc/self/cgroup

This PR applies to the following area(s)

FXServer, ScRT: JS

Successfully tested on

Game builds: N/A (server-only change)
Platforms: Windows

Built FXServer locally and reproduced #3978 end-to-end with mongodb@6 and mongoose@8.

Before:

[ c-scripting-node] Filesystem permission check from 'mongoose_test' for permission fs.read on resource 'C:\.dockerenv' - no device found
Error: Access to this API has been restricted. Use --allow-fs-read to manage permissions.

After (with matching add_unsafe_filesystem_absolute_read_permission):

[script:mongoose_test] MongoClient: connecting to mongodb://127.0.0.1:27017/fivem_test
[           resources] Started resource mongoose_test

Driver gets past getContainerMetadata() and continues normally.

Checklist

  • Code compiles and has been tested successfully.
  • Code explains itself well and/or is documented.
  • My commit message explains what the changes do and what they are for.
  • No extra compilation warnings are added by these changes.

Mongoose, mongodb and other Node libraries probe a small set of absolute
system paths during driver init (`/.dockerenv`, `/proc/self/cgroup`,
`/etc/os-release`, ...) to detect their runtime environment. Today these
probes are blocked unconditionally by `NodePermissionCallback` because
the path is not inside any VFS device, which surfaces as
"Access to this API has been restricted" and crashes the resource.

This change introduces an admin-opt-in allow-list:

- New `fx::ScriptingFilesystemAllowAbsoluteRead(absolutePath, resource)`
  helper, mirroring the shape of `AllowWrite` / `WorkerAllowSpawn`.
- New `add_unsafe_filesystem_absolute_read_permission <resource> <path>`
  console command, gated by the same `g_permissionModifyAllowed` flag
  as the other permission commands, so it can only be set during
  startup. The path must be absolute; matching is exact-or-directory-
  prefix (no glob, no traversal).
- `NodePermissionCallback` consults the allow-list only for
  `kFileSystemRead`, only when no VFS device matches the path, and only
  after the existing `..` traversal guard. Writes are unchanged.

Default behaviour is unchanged: without an explicit
`add_unsafe_filesystem_absolute_read_permission` entry the sandbox
behaves exactly as before.

Refs: citizenfx#3978
@github-actions github-actions Bot added triage Needs a preliminary assessment to determine the urgency and required action invalid Requires changes before it's considered valid and can be (re)triaged and removed triage Needs a preliminary assessment to determine the urgency and required action labels May 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

invalid Requires changes before it's considered valid and can be (re)triaged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Node.js Sandbox: Mongoose/MongoClient fails to initialize due to restricted fs.read access

1 participant