Skip to content

Commit 19aacdd

Browse files
committed
permission: drop process.permission.deny
1 parent 0094f90 commit 19aacdd

33 files changed

+415
-716
lines changed

benchmark/permission/permission-fs-deny.js

Lines changed: 0 additions & 19 deletions
This file was deleted.

doc/api/permissions.md

Lines changed: 3 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -492,24 +492,7 @@ using the [`--allow-child-process`][] and [`--allow-worker`][] respectively.
492492

493493
When enabling the Permission Model through the [`--experimental-permission`][]
494494
flag a new property `permission` is added to the `process` object.
495-
This property contains two functions:
496-
497-
##### `permission.deny(scope [,parameters])`
498-
499-
API call to deny permissions at runtime ([`permission.deny()`][])
500-
501-
```js
502-
process.permission.deny('fs'); // Deny permissions to ALL fs operations
503-
504-
// Deny permissions to ALL FileSystemWrite operations
505-
process.permission.deny('fs.write');
506-
// deny FileSystemWrite permissions to the protected-folder
507-
process.permission.deny('fs.write', ['/home/rafaelgss/protected-folder']);
508-
// Deny permissions to ALL FileSystemRead operations
509-
process.permission.deny('fs.read');
510-
// deny FileSystemRead permissions to the protected-folder
511-
process.permission.deny('fs.read', ['/home/rafaelgss/protected-folder']);
512-
```
495+
This property contains one function:
513496

514497
##### `permission.has(scope ,parameters)`
515498

@@ -519,10 +502,8 @@ API call to check permissions at runtime ([`permission.has()`][])
519502
process.permission.has('fs.write'); // true
520503
process.permission.has('fs.write', '/home/rafaelgss/protected-folder'); // true
521504

522-
process.permission.deny('fs.write', '/home/rafaelgss/protected-folder');
523-
524-
process.permission.has('fs.write'); // true
525-
process.permission.has('fs.write', '/home/rafaelgss/protected-folder'); // false
505+
process.permission.has('fs.read'); // true
506+
process.permission.has('fs.read', '/home/rafaelgss/protected-folder'); // false
526507
```
527508

528509
#### File System Permissions
@@ -560,39 +541,18 @@ There are constraints you need to know before using this system:
560541

561542
* Native modules are restricted by default when using the Permission Model.
562543
* Relative paths are not supported through the CLI (`--allow-fs-*`).
563-
The runtime API supports relative paths.
564544
* The model does not inherit to a child node process.
565545
* The model does not inherit to a worker thread.
566546
* When creating symlinks the target (first argument) should have read and
567547
write access.
568548
* Permission changes are not retroactively applied to existing resources.
569-
Consider the following snippet:
570-
```js
571-
const fs = require('node:fs');
572-
573-
// Open a fd
574-
const fd = fs.openSync('./README.md', 'r');
575-
// Then, deny access to all fs.read operations
576-
process.permission.deny('fs.read');
577-
// This call will NOT fail and the file will be read
578-
const data = fs.readFileSync(fd);
579-
```
580-
581-
Therefore, when possible, apply the permissions rules before any statement:
582-
583-
```js
584-
process.permission.deny('fs.read');
585-
const fd = fs.openSync('./README.md', 'r');
586-
// Error: Access to this API has been restricted
587-
```
588549

589550
[Security Policy]: https://github.com/nodejs/node/blob/main/SECURITY.md
590551
[`--allow-child-process`]: cli.md#--allow-child-process
591552
[`--allow-fs-read`]: cli.md#--allow-fs-read
592553
[`--allow-fs-write`]: cli.md#--allow-fs-write
593554
[`--allow-worker`]: cli.md#--allow-worker
594555
[`--experimental-permission`]: cli.md#--experimental-permission
595-
[`permission.deny()`]: process.md#processpermissiondenyscope-reference
596556
[`permission.has()`]: process.md#processpermissionhasscope-reference
597557
[import maps]: https://url.spec.whatwg.org/#relative-url-with-fragment-string
598558
[relative-url string]: https://url.spec.whatwg.org/#relative-url-with-fragment-string

doc/api/process.md

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2634,34 +2634,6 @@ This API is available through the [`--experimental-permission`][] flag.
26342634
for the current process. Additional documentation is available in the
26352635
[Permission Model][].
26362636
2637-
### `process.permission.deny(scope[, reference])`
2638-
2639-
<!-- YAML
2640-
added: REPLACEME
2641-
-->
2642-
2643-
* `scopes` {string}
2644-
* `reference` {Array}
2645-
* Returns: {boolean}
2646-
2647-
Deny permissions at runtime.
2648-
2649-
The available scopes are:
2650-
2651-
* `fs` - All File System
2652-
* `fs.read` - File System read operations
2653-
* `fs.write` - File System write operations
2654-
2655-
The reference has a meaning based on the provided scope. For example,
2656-
the reference when the scope is File System means files and folders.
2657-
2658-
```js
2659-
// Deny READ operations to the ./README.md file
2660-
process.permission.deny('fs.read', ['./README.md']);
2661-
// Deny ALL WRITE operations
2662-
process.permission.deny('fs.write');
2663-
```
2664-
26652637
### `process.permission.has(scope[, reference])`
26662638
26672639
<!-- YAML

src/env.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -784,10 +784,10 @@ Environment::Environment(IsolateData* isolate_data,
784784
if (!options_->allow_fs_read.empty() || !options_->allow_fs_write.empty()) {
785785
options_->allow_native_addons = false;
786786
if (!options_->allow_child_process) {
787-
permission()->Deny(permission::PermissionScope::kChildProcess, {});
787+
permission()->Apply("*", permission::PermissionScope::kChildProcess);
788788
}
789789
if (!options_->allow_worker_threads) {
790-
permission()->Deny(permission::PermissionScope::kWorkerThreads, {});
790+
permission()->Apply("*", permission::PermissionScope::kWorkerThreads);
791791
}
792792
}
793793

src/permission/child_process_permission.cc

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,8 @@ namespace permission {
1010
// Currently, ChildProcess manage a single state
1111
// Once denied, it's always denied
1212
void ChildProcessPermission::Apply(const std::string& deny,
13-
PermissionScope scope) {}
14-
15-
bool ChildProcessPermission::Deny(PermissionScope perm,
16-
const std::vector<std::string>& params) {
13+
PermissionScope scope) {
1714
deny_all_ = true;
18-
return true;
1915
}
2016

2117
bool ChildProcessPermission::is_granted(PermissionScope perm,

src/permission/child_process_permission.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ namespace permission {
1313
class ChildProcessPermission final : public PermissionBase {
1414
public:
1515
void Apply(const std::string& deny, PermissionScope scope) override;
16-
bool Deny(PermissionScope scope,
17-
const std::vector<std::string>& params) override;
1816
bool is_granted(PermissionScope perm,
1917
const std::string_view& param = "") override;
2018

src/permission/fs_permission.cc

Lines changed: 5 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@ void FreeRecursivelyNode(
4848
delete node;
4949
}
5050

51-
bool is_tree_granted(node::permission::FSPermission::RadixTree* deny_tree,
52-
node::permission::FSPermission::RadixTree* granted_tree,
51+
bool is_tree_granted(node::permission::FSPermission::RadixTree* granted_tree,
5352
const std::string_view& param) {
5453
#ifdef _WIN32
5554
// is UNC file path
@@ -60,11 +59,10 @@ bool is_tree_granted(node::permission::FSPermission::RadixTree* deny_tree,
6059
starting_pos += 4; // "UNC\"
6160
}
6261
auto normalized = param.substr(starting_pos);
63-
return !deny_tree->Lookup(normalized) &&
64-
granted_tree->Lookup(normalized, true);
62+
return granted_tree->Lookup(normalized, true);
6563
}
6664
#endif
67-
return !deny_tree->Lookup(param) && granted_tree->Lookup(param, true);
65+
return granted_tree->Lookup(param, true);
6866
}
6967

7068
} // namespace
@@ -91,40 +89,6 @@ void FSPermission::Apply(const std::string& allow, PermissionScope scope) {
9189
}
9290
}
9391

94-
bool FSPermission::Deny(PermissionScope perm,
95-
const std::vector<std::string>& params) {
96-
if (perm == PermissionScope::kFileSystem) {
97-
deny_all_in_ = true;
98-
deny_all_out_ = true;
99-
return true;
100-
}
101-
102-
bool deny_all = params.size() == 0;
103-
if (perm == PermissionScope::kFileSystemRead) {
104-
if (deny_all) deny_all_in_ = true;
105-
// when deny_all_in is already true permission.deny should be idempotent
106-
if (deny_all_in_) return true;
107-
allow_all_in_ = false;
108-
for (auto& param : params) {
109-
deny_in_fs_.Insert(WildcardIfDir(param));
110-
}
111-
return true;
112-
}
113-
114-
if (perm == PermissionScope::kFileSystemWrite) {
115-
if (deny_all) deny_all_out_ = true;
116-
// when deny_all_out is already true permission.deny should be idempotent
117-
if (deny_all_out_) return true;
118-
allow_all_out_ = false;
119-
120-
for (auto& param : params) {
121-
deny_out_fs_.Insert(WildcardIfDir(param));
122-
}
123-
return true;
124-
}
125-
return false;
126-
}
127-
12892
void FSPermission::GrantAccess(PermissionScope perm, std::string res) {
12993
const std::string path = WildcardIfDir(res);
13094
if (perm == PermissionScope::kFileSystemRead) {
@@ -144,11 +108,11 @@ bool FSPermission::is_granted(PermissionScope perm,
144108
case PermissionScope::kFileSystemRead:
145109
return !deny_all_in_ &&
146110
((param.empty() && allow_all_in_) || allow_all_in_ ||
147-
is_tree_granted(&deny_in_fs_, &granted_in_fs_, param));
111+
is_tree_granted(&granted_in_fs_, param));
148112
case PermissionScope::kFileSystemWrite:
149113
return !deny_all_out_ &&
150114
((param.empty() && allow_all_out_) || allow_all_out_ ||
151-
is_tree_granted(&deny_out_fs_, &granted_out_fs_, param));
115+
is_tree_granted(&granted_out_fs_, param));
152116
default:
153117
return false;
154118
}

src/permission/fs_permission.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ namespace permission {
1717
class FSPermission final : public PermissionBase {
1818
public:
1919
void Apply(const std::string& deny, PermissionScope scope) override;
20-
bool Deny(PermissionScope scope,
21-
const std::vector<std::string>& params) override;
2220
bool is_granted(PermissionScope perm, const std::string_view& param) override;
2321

2422
// For debugging purposes, use the gist function to print the whole tree
@@ -135,18 +133,9 @@ class FSPermission final : public PermissionBase {
135133
void GrantAccess(PermissionScope scope, std::string param);
136134
void RestrictAccess(PermissionScope scope,
137135
const std::vector<std::string>& params);
138-
// /tmp/* --grant
139-
// /tmp/dsadsa/t.js denied in runtime
140-
//
141-
// /tmp/text.txt -- grant
142-
// /tmp/text.txt -- denied in runtime
143-
//
144136
// fs granted on startup
145137
RadixTree granted_in_fs_;
146138
RadixTree granted_out_fs_;
147-
// fs denied in runtime
148-
RadixTree deny_in_fs_;
149-
RadixTree deny_out_fs_;
150139

151140
bool deny_all_in_ = true;
152141
bool deny_all_out_ = true;

src/permission/permission.cc

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,8 @@
1414

1515
namespace node {
1616

17-
using v8::Array;
1817
using v8::Context;
1918
using v8::FunctionCallbackInfo;
20-
using v8::Integer;
2119
using v8::Local;
2220
using v8::Object;
2321
using v8::String;
@@ -27,42 +25,6 @@ namespace permission {
2725

2826
namespace {
2927

30-
// permission.deny('fs.read', ['/tmp/'])
31-
// permission.deny('fs.read')
32-
static void Deny(const FunctionCallbackInfo<Value>& args) {
33-
Environment* env = Environment::GetCurrent(args);
34-
v8::Isolate* isolate = env->isolate();
35-
CHECK(args[0]->IsString());
36-
std::string deny_scope = *String::Utf8Value(isolate, args[0]);
37-
PermissionScope scope = Permission::StringToPermission(deny_scope);
38-
if (scope == PermissionScope::kPermissionsRoot) {
39-
return args.GetReturnValue().Set(false);
40-
}
41-
42-
std::vector<std::string> params;
43-
if (args.Length() == 1 || args[1]->IsUndefined()) {
44-
return args.GetReturnValue().Set(env->permission()->Deny(scope, params));
45-
}
46-
47-
CHECK(args[1]->IsArray());
48-
Local<Array> js_params = Local<Array>::Cast(args[1]);
49-
Local<Context> context = isolate->GetCurrentContext();
50-
51-
for (uint32_t i = 0; i < js_params->Length(); ++i) {
52-
Local<Value> arg;
53-
if (!js_params->Get(context, Integer::New(isolate, i)).ToLocal(&arg)) {
54-
return;
55-
}
56-
String::Utf8Value utf8_arg(isolate, arg);
57-
if (*utf8_arg == nullptr) {
58-
return;
59-
}
60-
params.push_back(*utf8_arg);
61-
}
62-
63-
return args.GetReturnValue().Set(env->permission()->Deny(scope, params));
64-
}
65-
6628
// permission.has('fs.in', '/tmp/')
6729
// permission.has('fs.in')
6830
static void Has(const FunctionCallbackInfo<Value>& args) {
@@ -169,27 +131,16 @@ void Permission::Apply(const std::string& allow, PermissionScope scope) {
169131
}
170132
}
171133

172-
bool Permission::Deny(PermissionScope scope,
173-
const std::vector<std::string>& params) {
174-
auto permission = nodes_.find(scope);
175-
if (permission != nodes_.end()) {
176-
return permission->second->Deny(scope, params);
177-
}
178-
return false;
179-
}
180-
181134
void Initialize(Local<Object> target,
182135
Local<Value> unused,
183136
Local<Context> context,
184137
void* priv) {
185-
SetMethod(context, target, "deny", Deny);
186138
SetMethodNoSideEffect(context, target, "has", Has);
187139

188140
target->SetIntegrityLevel(context, v8::IntegrityLevel::kFrozen).FromJust();
189141
}
190142

191143
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
192-
registry->Register(Deny);
193144
registry->Register(Has);
194145
}
195146

src/permission/permission.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ class Permission {
4747

4848
// CLI Call
4949
void Apply(const std::string& deny, PermissionScope scope);
50-
// Permission.Deny API
51-
bool Deny(PermissionScope scope, const std::vector<std::string>& params);
5250
void EnablePermissions();
5351

5452
private:

src/permission/permission_base.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ enum class PermissionScope {
3737
class PermissionBase {
3838
public:
3939
virtual void Apply(const std::string& deny, PermissionScope scope) = 0;
40-
virtual bool Deny(PermissionScope scope,
41-
const std::vector<std::string>& params) = 0;
4240
virtual bool is_granted(PermissionScope perm,
4341
const std::string_view& param = "") = 0;
4442
};

src/permission/worker_permission.cc

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,8 @@ namespace permission {
99

1010
// Currently, PolicyDenyWorker manage a single state
1111
// Once denied, it's always denied
12-
void WorkerPermission::Apply(const std::string& deny, PermissionScope scope) {}
13-
14-
bool WorkerPermission::Deny(PermissionScope perm,
15-
const std::vector<std::string>& params) {
12+
void WorkerPermission::Apply(const std::string& deny, PermissionScope scope) {
1613
deny_all_ = true;
17-
return true;
1814
}
1915

2016
bool WorkerPermission::is_granted(PermissionScope perm,

src/permission/worker_permission.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ namespace permission {
1313
class WorkerPermission final : public PermissionBase {
1414
public:
1515
void Apply(const std::string& deny, PermissionScope scope) override;
16-
bool Deny(PermissionScope scope,
17-
const std::vector<std::string>& params) override;
1816
bool is_granted(PermissionScope perm,
1917
const std::string_view& param = "") override;
2018

0 commit comments

Comments
 (0)