Skip to content

Commit ea66a82

Browse files
committed
permission,net,dgram: add permission for net
1 parent ce531af commit ea66a82

File tree

16 files changed

+735
-1
lines changed

16 files changed

+735
-1
lines changed

doc/api/cli.md

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,176 @@ Error: Access to this API has been restricted
357357
}
358358
```
359359

360+
### `--allow-net-tcp-in`
361+
362+
<!-- YAML
363+
added: REPLACEME
364+
-->
365+
366+
> Stability: 1.1 - Active development
367+
368+
When using the [Permission Model][], the process will not be able to bind to any
369+
ip or port by default. Attempts to do so will throw an `ERR_ACCESS_DENIED` unless
370+
the user explicitly passes the `--allow-net-tcp-in` flag when starting Node.js.
371+
372+
The valid arguments for the `--allow-net-tcp-in` flag are:
373+
374+
* `*` - To allow all `bind` operations.
375+
* Multiple addresses can be allowed using multiple `--allow-net-tcp-in` flags.
376+
Example `--allow-net-tcp-in=127.0.0.1:8080 --allow-net-tcp-in=127.0.0.1:9090`
377+
378+
Example:
379+
380+
```js
381+
const net = require('node:net');
382+
net.createServer().listen(9297, '127.0.0.1')
383+
```
384+
385+
```console
386+
$ node --experimental-permission --allow-fs-read=./index.js index.js
387+
node:net:1840
388+
err = handle.bind(address, port);
389+
^
390+
391+
Error: Access to this API has been restricted
392+
at createServerHandle (node:net:1840:20)
393+
at Server.setupListenHandle [as _listen2] (node:net:1879:14)
394+
at listenInCluster (node:net:1961:12)
395+
at doListen (node:net:2135:7)
396+
at process.processTicksAndRejections (node:internal/process/task_queues:83:21) {
397+
code: 'ERR_ACCESS_DENIED',
398+
permission: 'NetTCPIn',
399+
resource: '127.0.0.1/9297'
400+
}
401+
```
402+
403+
### `--allow-net-tcp-out`
404+
405+
<!-- YAML
406+
added: REPLACEME
407+
-->
408+
409+
> Stability: 1.1 - Active development
410+
411+
When using the [Permission Model][], the process will not be able to connect to any
412+
ip or port by default. Attempts to do so will throw an `ERR_ACCESS_DENIED` unless
413+
the user explicitly passes the `--allow-net-tcp-out` flag when starting Node.js.
414+
415+
The valid arguments for the `--allow-net-tcp-out` flag are:
416+
417+
* `*` - To allow all `connect` operations.
418+
* Multiple addresses can be allowed using multiple `--allow-net-tcp-out` flags.
419+
Example `--allow-net-tcp-out=127.0.0.1:8080 --allow-net-tcp-out=127.0.0.1:9090`
420+
421+
Example:
422+
423+
```js
424+
const net = require('node:net');
425+
net.connect(9297, '127.0.0.1');
426+
```
427+
428+
```console
429+
$ node --experimental-permission --allow-fs-read=./index.js index.js
430+
node:net:1075
431+
err = self._handle.connect(req, address, port);
432+
^
433+
434+
Error: Access to this API has been restricted
435+
at internalConnect (node:net:1075:26)
436+
at defaultTriggerAsyncIdScope (node:internal/async_hooks:464:18)
437+
at node:net:1324:9
438+
at process.processTicksAndRejections (node:internal/process/task_queues:77:11) {
439+
code: 'ERR_ACCESS_DENIED',
440+
permission: 'NetTCPOut',
441+
resource: '127.0.0.1/9297'
442+
}
443+
444+
```
445+
446+
### `--allow-net-udp-in`
447+
448+
<!-- YAML
449+
added: REPLACEME
450+
-->
451+
452+
> Stability: 1.1 - Active development
453+
454+
When using the [Permission Model][], the process will not be able to bind to any
455+
ip or port by default. Attempts to do so will throw an `ERR_ACCESS_DENIED` unless
456+
the user explicitly passes the `--allow-net-udp-in` flag when starting Node.js.
457+
458+
The valid arguments for the `--allow-net-udp-in` flag are:
459+
460+
* `*` - To allow all `bind` operations.
461+
* Multiple addresses can be allowed using multiple `--allow-net-udp-in` flags.
462+
Example `--allow-net-udp-in=127.0.0.1:8080 --allow-net-udp-in=127.0.0.1:9090`
463+
464+
Example:
465+
466+
```js
467+
const dgram = require('node:dgram');
468+
dgram.createSocket('udp4').bind(9000, '127.0.0.1')
469+
```
470+
471+
```console
472+
$ node --experimental-permission --allow-fs-read=./index.js index.js
473+
node:dgram:364
474+
const err = state.handle.bind(ip, port || 0, flags);
475+
^
476+
477+
Error: Access to this API has been restricted
478+
at node:dgram:364:32
479+
at process.processTicksAndRejections (node:internal/process/task_queues:83:21) {
480+
code: 'ERR_ACCESS_DENIED',
481+
permission: 'NetUDPIn',
482+
resource: '127.0.0.1/9297'
483+
}
484+
```
485+
486+
### `--allow-net-udp-out`
487+
488+
<!-- YAML
489+
added: REPLACEME
490+
-->
491+
492+
> Stability: 1.1 - Active development
493+
494+
When using the [Permission Model][], the process will not be able to connect to any
495+
ip or port by default. Attempts to do so will throw an `ERR_ACCESS_DENIED` unless
496+
the user explicitly passes the `--allow-net-udp-out` flag when starting Node.js.
497+
498+
The valid arguments for the `--allow-net-udp-out` flag are:
499+
500+
* `*` - To allow all `connect` operations.
501+
* Multiple addresses can be allowed using multiple `--allow-net-udp-out` flags.
502+
Example `--allow-net-udp-out=127.0.0.1:8080 --allow-net-udp-out=127.0.0.1:9090`
503+
504+
Example:
505+
506+
```js
507+
const dgram = require('node:dgram');
508+
dgram.createSocket('udp4').bind(8000, '127.0.0.1', function () {
509+
this.connect(9001, '127.0.0.1')
510+
});
511+
```
512+
513+
```console
514+
$ node --experimental-permission --allow-net-udp-in=127.0.0.1/8000 --allow-fs-read=./index.js index.js
515+
node:dgram:433
516+
const err = state.handle.connect(ip, port);
517+
^
518+
519+
Error: Access to this API has been restricted
520+
at doConnect (node:dgram:433:30)
521+
at defaultTriggerAsyncIdScope (node:internal/async_hooks:464:18)
522+
at afterDns (node:dgram:416:5)
523+
at process.processTicksAndRejections (node:internal/process/task_queues:83:21) {
524+
code: 'ERR_ACCESS_DENIED',
525+
permission: 'NetUDPOut',
526+
resource: '127.0.0.1/9001'
527+
}
528+
```
529+
360530
### `--build-snapshot`
361531

362532
<!-- YAML
@@ -1012,6 +1182,8 @@ following permissions are restricted:
10121182
* Child Process - manageable through [`--allow-child-process`][] flag
10131183
* Worker Threads - manageable through [`--allow-worker`][] flag
10141184
* WASI - manageable through [`--allow-wasi`][] flag
1185+
* Net - manageable through [`--allow-net-tcp-in`][], [`--allow-net-tcp-out`][],
1186+
[`--allow-net-udp-in`][] and [`--allow-net-udp-out`][] flags
10151187

10161188
### `--experimental-require-module`
10171189

@@ -2804,6 +2976,10 @@ one is included in the list below.
28042976
* `--allow-child-process`
28052977
* `--allow-fs-read`
28062978
* `--allow-fs-write`
2979+
* `--allow-net-tcp-in`
2980+
* `--allow-net-tcp-out`
2981+
* `--allow-net-udp-in`
2982+
* `--allow-net-udp-out`
28072983
* `--allow-wasi`
28082984
* `--allow-worker`
28092985
* `--conditions`, `-C`
@@ -3356,6 +3532,10 @@ node --stack-trace-limit=12 -p -e "Error.stackTraceLimit" # prints 12
33563532
[`--allow-child-process`]: #--allow-child-process
33573533
[`--allow-fs-read`]: #--allow-fs-read
33583534
[`--allow-fs-write`]: #--allow-fs-write
3535+
[`--allow-net-tcp-in`]: #--allow-net-tcp-in
3536+
[`--allow-net-tcp-out`]: #--allow-net-tcp-out
3537+
[`--allow-net-udp-in`]: #--allow-net-udp-in
3538+
[`--allow-net-udp-out`]: #--allow-net-udp-out
33593539
[`--allow-wasi`]: #--allow-wasi
33603540
[`--allow-worker`]: #--allow-worker
33613541
[`--build-snapshot`]: #--build-snapshot

doc/api/permissions.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,9 @@ using the [`--allow-child-process`][] and [`--allow-worker`][] respectively.
509509
To allow native addons when using permission model, use the [`--allow-addons`][]
510510
flag. For WASI, use the [`--allow-wasi`][] flag.
511511

512+
For net, use the [`--allow-net-tcp-in`][], [`--allow-net-tcp-out`][],
513+
[`--allow-net-udp-in`][] and [`--allow-net-udp-out`][] flags.
514+
512515
#### Runtime API
513516

514517
When enabling the Permission Model through the [`--experimental-permission`][]
@@ -575,6 +578,7 @@ There are constraints you need to know before using this system:
575578
* Inspector protocol
576579
* File system access
577580
* WASI
581+
* DNS
578582
* The Permission Model is initialized after the Node.js environment is set up.
579583
However, certain flags such as `--env-file` or `--openssl-config` are designed
580584
to read files before environment initialization. As a result, such flags are
@@ -598,6 +602,10 @@ There are constraints you need to know before using this system:
598602
[`--allow-child-process`]: cli.md#--allow-child-process
599603
[`--allow-fs-read`]: cli.md#--allow-fs-read
600604
[`--allow-fs-write`]: cli.md#--allow-fs-write
605+
[`--allow-net-tcp-in`]: cli.md#--allow-net-tcp-in
606+
[`--allow-net-tcp-out`]: cli.md#--allow-net-tcp-out
607+
[`--allow-net-udp-in`]: cli.md#--allow-net-udp-in
608+
[`--allow-net-udp-out`]: cli.md#--allow-net-udp-out
601609
[`--allow-wasi`]: cli.md#--allow-wasi
602610
[`--allow-worker`]: cli.md#--allow-worker
603611
[`--experimental-permission`]: cli.md#--experimental-permission

doc/node.1

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,18 @@ Allow execution of WASI when using the permission model.
9494
.It Fl -allow-worker
9595
Allow creating worker threads when using the permission model.
9696
.
97+
.It Fl -allow-net-tcp-in
98+
Allow bind when using the permission model.
99+
.
100+
.It Fl -allow-net-tcp-out
101+
Allow connect when using the permission model.
102+
.
103+
.It Fl -allow-net-udp-in
104+
Allow bind when using the permission model.
105+
.
106+
.It Fl -allow-net-udp-out
107+
Allow connect when using the permission model.
108+
.
97109
.It Fl -completion-bash
98110
Print source-able bash completion script for Node.js.
99111
.

lib/internal/process/pre_execution.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,10 @@ function initializePermission() {
530530
const warnFlags = [
531531
'--allow-addons',
532532
'--allow-child-process',
533+
'--allow-net-tcp-in',
534+
'--allow-net-tcp-out',
535+
'--allow-net-udp-in',
536+
'--allow-net-udp-out',
533537
'--allow-wasi',
534538
'--allow-worker',
535539
];
@@ -574,6 +578,10 @@ function initializePermission() {
574578
'--allow-child-process',
575579
'--allow-wasi',
576580
'--allow-worker',
581+
'--allow-net-tcp-in',
582+
'--allow-net-tcp-out',
583+
'--allow-net-udp-in',
584+
'--allow-net-udp-out',
577585
];
578586
ArrayPrototypeForEach(availablePermissionFlags, (flag) => {
579587
const value = getOptionValue(flag);

node.gyp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@
155155
'src/permission/permission.cc',
156156
'src/permission/wasi_permission.cc',
157157
'src/permission/worker_permission.cc',
158+
'src/permission/net_permission.cc',
158159
'src/pipe_wrap.cc',
159160
'src/process_wrap.cc',
160161
'src/signal_wrap.cc',
@@ -280,6 +281,7 @@
280281
'src/permission/permission.h',
281282
'src/permission/wasi_permission.h',
282283
'src/permission/worker_permission.h',
284+
'src/permission/net_permission.h',
283285
'src/pipe_wrap.h',
284286
'src/req_wrap.h',
285287
'src/req_wrap-inl.h',

src/env.cc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,26 @@ Environment::Environment(IsolateData* isolate_data,
936936
options_->allow_fs_write,
937937
permission::PermissionScope::kFileSystemWrite);
938938
}
939+
if (!options_->allow_net_tcp_in.empty()) {
940+
permission()->Apply(this,
941+
options_->allow_net_tcp_in,
942+
permission::PermissionScope::kNetTCPIn);
943+
}
944+
if (!options_->allow_net_tcp_out.empty()) {
945+
permission()->Apply(this,
946+
options_->allow_net_tcp_out,
947+
permission::PermissionScope::kNetTCPOut);
948+
}
949+
if (!options_->allow_net_udp_in.empty()) {
950+
permission()->Apply(this,
951+
options_->allow_net_udp_in,
952+
permission::PermissionScope::kNetUDPIn);
953+
}
954+
if (!options_->allow_net_udp_out.empty()) {
955+
permission()->Apply(this,
956+
options_->allow_net_udp_out,
957+
permission::PermissionScope::kNetUDPOut);
958+
}
939959
}
940960
}
941961

src/node_options.cc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,22 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
464464
"allow worker threads when any permissions are set",
465465
&EnvironmentOptions::allow_worker_threads,
466466
kAllowedInEnvvar);
467+
AddOption("--allow-net-tcp-in",
468+
"allow host:port or ip:port to listen when any permissions are set",
469+
&EnvironmentOptions::allow_net_tcp_in,
470+
kAllowedInEnvvar);
471+
AddOption("--allow-net-tcp-out",
472+
"allow host:port or ip:port to dial when any permissions are set",
473+
&EnvironmentOptions::allow_net_tcp_out,
474+
kAllowedInEnvvar);
475+
AddOption("--allow-net-udp-in",
476+
"allow host:port or ip:port to bind when any permissions are set",
477+
&EnvironmentOptions::allow_net_udp_in,
478+
kAllowedInEnvvar);
479+
AddOption("--allow-net-udp-out",
480+
"allow host:port or ip:port to connect when any permissions are set",
481+
&EnvironmentOptions::allow_net_udp_out,
482+
kAllowedInEnvvar);
467483
AddOption("--experimental-repl-await",
468484
"experimental await keyword support in REPL",
469485
&EnvironmentOptions::experimental_repl_await,

src/node_options.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ class EnvironmentOptions : public Options {
132132
bool allow_child_process = false;
133133
bool allow_wasi = false;
134134
bool allow_worker_threads = false;
135+
std::vector<std::string> allow_net_tcp_in;
136+
std::vector<std::string> allow_net_tcp_out;
137+
std::vector<std::string> allow_net_udp_in;
138+
std::vector<std::string> allow_net_udp_out;
135139
bool experimental_repl_await = true;
136140
bool experimental_vm_modules = false;
137141
bool expose_internals = false;

0 commit comments

Comments
 (0)