Skip to content

Commit fd5efac

Browse files
RafaelGSSrichardlau
authored andcommitted
src,permission: add --allow-addon flag
PR-URL: #51183 Reviewed-By: Marco Ippolito <[email protected]> Reviewed-By: Paolo Insogna <[email protected]>
1 parent f4987eb commit fd5efac

10 files changed

+94
-1
lines changed

doc/api/cli.md

+42
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,47 @@ If this flag is passed, the behavior can still be set to not abort through
103103
[`process.setUncaughtExceptionCaptureCallback()`][] (and through usage of the
104104
`node:domain` module that uses it).
105105

106+
### `--allow-addons`
107+
108+
<!-- YAML
109+
added: REPLACEME
110+
-->
111+
112+
> Stability: 1.1 - Active development
113+
114+
When using the [Permission Model][], the process will not be able to use
115+
native addons by default.
116+
Attempts to do so will throw an `ERR_DLOPEN_DISABLED` unless the
117+
user explicitly passes the `--allow-addons` flag when starting Node.js.
118+
119+
Example:
120+
121+
```cjs
122+
// Attempt to require an native addon
123+
require('nodejs-addon-example');
124+
```
125+
126+
```console
127+
$ node --experimental-permission --allow-fs-read=* index.js
128+
node:internal/modules/cjs/loader:1319
129+
return process.dlopen(module, path.toNamespacedPath(filename));
130+
^
131+
132+
Error: Cannot load native addon because loading addons is disabled.
133+
at Module._extensions..node (node:internal/modules/cjs/loader:1319:18)
134+
at Module.load (node:internal/modules/cjs/loader:1091:32)
135+
at Module._load (node:internal/modules/cjs/loader:938:12)
136+
at Module.require (node:internal/modules/cjs/loader:1115:19)
137+
at require (node:internal/modules/helpers:130:18)
138+
at Object.<anonymous> (/home/index.js:1:15)
139+
at Module._compile (node:internal/modules/cjs/loader:1233:14)
140+
at Module._extensions..js (node:internal/modules/cjs/loader:1287:10)
141+
at Module.load (node:internal/modules/cjs/loader:1091:32)
142+
at Module._load (node:internal/modules/cjs/loader:938:12) {
143+
code: 'ERR_DLOPEN_DISABLED'
144+
}
145+
```
146+
106147
### `--allow-child-process`
107148

108149
<!-- YAML
@@ -2369,6 +2410,7 @@ Node.js options that are allowed are:
23692410

23702411
<!-- node-options-node start -->
23712412

2413+
* `--allow-addons`
23722414
* `--allow-child-process`
23732415
* `--allow-fs-read`
23742416
* `--allow-fs-write`

doc/api/permissions.md

+4
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,9 @@ Error: Access to this API has been restricted
506506
Allowing access to spawning a process and creating worker threads can be done
507507
using the [`--allow-child-process`][] and [`--allow-worker`][] respectively.
508508

509+
To allow native addons when using permission model, use the [`--allow-addons`][]
510+
flag.
511+
509512
#### Runtime API
510513

511514
When enabling the Permission Model through the [`--experimental-permission`][]
@@ -591,6 +594,7 @@ There are constraints you need to know before using this system:
591594

592595
[Import maps]: https://url.spec.whatwg.org/#relative-url-with-fragment-string
593596
[Security Policy]: https://github.com/nodejs/node/blob/main/SECURITY.md
597+
[`--allow-addons`]: cli.md#--allow-addons
594598
[`--allow-child-process`]: cli.md#--allow-child-process
595599
[`--allow-fs-read`]: cli.md#--allow-fs-read
596600
[`--allow-fs-write`]: cli.md#--allow-fs-write

doc/node.1

+3
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ Allow file system read access when using the permission model.
8282
.It Fl -allow-fs-write
8383
Allow file system write access when using the permission model.
8484
.
85+
.It Fl -allow-addons
86+
Allow using native addons when using the permission model.
87+
.
8588
.It Fl -allow-child-process
8689
Allow spawning process when using the permission model.
8790
.

lib/internal/process/pre_execution.js

+2
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,7 @@ function initializePermission() {
604604
'ExperimentalWarning');
605605
const { has, deny } = require('internal/process/permission');
606606
const warnFlags = [
607+
'--allow-addons',
607608
'--allow-child-process',
608609
'--allow-worker',
609610
];
@@ -644,6 +645,7 @@ function initializePermission() {
644645
const availablePermissionFlags = [
645646
'--allow-fs-read',
646647
'--allow-fs-write',
648+
'--allow-addons',
647649
'--allow-child-process',
648650
'--allow-worker',
649651
];

src/env.cc

+3-1
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,9 @@ Environment::Environment(IsolateData* isolate_data,
894894
// The process shouldn't be able to neither
895895
// spawn/worker nor use addons or enable inspector
896896
// unless explicitly allowed by the user
897-
options_->allow_native_addons = false;
897+
if (!options_->allow_addons) {
898+
options_->allow_native_addons = false;
899+
}
898900
flags_ = flags_ | EnvironmentFlags::kNoCreateInspector;
899901
permission()->Apply({"*"}, permission::PermissionScope::kInspector);
900902
if (!options_->allow_child_process) {

src/node_options.cc

+4
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,10 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
442442
"allow permissions to write in the filesystem",
443443
&EnvironmentOptions::allow_fs_write,
444444
kAllowedInEnvvar);
445+
AddOption("--allow-addons",
446+
"allow use of addons when any permissions are set",
447+
&EnvironmentOptions::allow_addons,
448+
kAllowedInEnvvar);
445449
AddOption("--allow-child-process",
446450
"allow use of child process when any permissions are set",
447451
&EnvironmentOptions::allow_child_process,

src/node_options.h

+1
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ class EnvironmentOptions : public Options {
122122
bool experimental_permission = false;
123123
std::vector<std::string> allow_fs_read;
124124
std::vector<std::string> allow_fs_write;
125+
bool allow_addons = false;
125126
bool allow_child_process = false;
126127
bool allow_worker_threads = false;
127128
bool experimental_repl_await = true;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Flags: --experimental-permission --allow-addons --allow-fs-read=*
2+
'use strict';
3+
4+
const common = require('../common');
5+
common.skipIfWorker();
6+
7+
const { createRequire } = require('node:module');
8+
const assert = require('node:assert');
9+
const fixtures = require('../common/fixtures');
10+
const loadFixture = createRequire(fixtures.path('node_modules'));
11+
// When a permission is set by cli, the process shouldn't be able
12+
// to require native addons unless --allow-addons is sent
13+
{
14+
// doesNotThrow
15+
const msg = loadFixture('pkgexports/no-addons');
16+
assert.strictEqual(msg, 'using native addons');
17+
}
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Flags: --experimental-permission --allow-fs-read=*
2+
'use strict';
3+
4+
const common = require('../common');
5+
common.skipIfWorker();
6+
7+
const { createRequire } = require('node:module');
8+
const assert = require('node:assert');
9+
const fixtures = require('../common/fixtures');
10+
const loadFixture = createRequire(fixtures.path('node_modules'));
11+
// When a permission is set by cli, the process shouldn't be able
12+
// to require native addons unless --allow-addons is sent
13+
{
14+
// doesNotThrow
15+
const msg = loadFixture('pkgexports/no-addons');
16+
assert.strictEqual(msg, 'not using native addons');
17+
}

test/parallel/test-permission-warning-flags.js

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const { spawnSync } = require('child_process');
55
const assert = require('assert');
66

77
const warnFlags = [
8+
'--allow-addons',
89
'--allow-child-process',
910
'--allow-worker',
1011
];

0 commit comments

Comments
 (0)