Repository navigation
Runtime Permission Dropping (process.permission.drop() #62223
Description
What is the problem this feature will solve?
The current Permission Model (--allow-fs-read, --allow-fs-write, --allow-child-process, --allow-worker, --experimental-permission) is all-or-nothing at startup. You declare the full set of permissions when launching the process, and they remain fixed for its entire lifetime.
This makes it impossible to implement a common and well-established security pattern: start with the permissions you need for initialization, then drop the ones you no longer need before entering the main event loop.
Real-world Node.js applications routinely need broad permissions at startup (reading config files, loading TLS certificates, binding to privileged ports, spawning setup workers) but then operate in a much narrower scope for the rest of their lifetime. Today, there is no way to tighten the permission boundary after initialization.
What is the feature you are proposing to solve the problem?
const fs = require('node:fs');
// Startup: read config and certs (needs broad fs read)
const config = JSON.parse(fs.readFileSync('/etc/myapp/config.json', 'utf8'));
const cert = fs.readFileSync(config.tlsCertPath);
const key = fs.readFileSync(config.tlsKeyPath);
// Drop permissions we no longer need
process.permission.drop('fs.read', '/etc/myapp');
process.permission.drop('child');
process.permission.drop('worker');
// From here on, the process can no longer read /etc/myapp,
// spawn child processes, or create workers.
// Any attempt to do so throws ERR_ACCESS_DENIED.A drop() call removes the specified permission from the internal allow-list. It cannot be reversed through process.permission or any other Node.js API. This narrows the set of resources reachable through standard Node.js APIs (fs, child_process, net, etc.), which is where path traversal and similar attacks operate.
As with the rest of the Permission Model, drop() is not a hard process-level security boundary. It does not protect against malicious code with arbitrary V8 access that bypasses Node.js APIs entirely (see Security model).
What alternatives have you considered?
No response
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsAwaiting Triage
Activity
mcollina commentedon Mar 12, 2026
cc @nodejs/security-wg
absidue commentedon Mar 12, 2026
What should happen to resources that are still open/running when a permission is dropped? Should file handles be closed, workers and child processes terminated automatically when drop is called? Native addons would be more complicated to unload, because as far as I understand Node.js doesn't currently have a way of doing that.
ChALkeR commentedon Mar 12, 2026
The idea is great, and I'm in favor
This should be noted though that the "drop permissions" mental model is in somewhat contradiction with the security model which assumes running trusted code only
Which is not theoretical: it leads us to a point that (A) js being able to write to raw process memory not a security issue per model (B) and some in-process protection mechanisms are considered security features
I.e. this is unlikely to be robust against malicious JS:
A better documentation on this should signal that those are not hard process-level security mechanisms and can't be expected to be not bypassable with js code executed after the "drop"
mcollina commentedon Mar 12, 2026
Everything that has happened before the drop would stay. That's the goal of the feature.
absidue commentedon Mar 12, 2026
In that case if/when permission dropping is implemented it should be clearly documented that dropping permissions at runtime should not be treated as equal to never granting them in the first place, so that people are aware that they still need to be careful what permissions they grant and what they do before dropping a permission, to avoid malicious actors piggybacking on things that were left open/running. As one might naively assume that revoking a permission would also revoke access to all existing resources that were previously granted through that permission, which is how other permission systems work (if I block your SSH access to a server it should not only block new sessions but also terminate all running sessions).
RafaelGSS commentedon Mar 12, 2026
+1 - I can work on it if you don't need to rush on it.
mcollina commentedon Mar 12, 2026
Go ahead! Not needed immediately but something that would be good to have.
(I would have thrown this at the clanker)
mcollina commentedon Mar 12, 2026
@ChALkeR description updated
absidue commentedon Mar 12, 2026
Just to be clear I am +1 on this too.
ChALkeR commentedon Mar 13, 2026
@mcollina This is still unclear I think?
Same-process memory writes are achievable from Node.js APIs (even though undocumented)
And Node.js security model does not protect against that
It doesn't need the C++ V8 APIs (which is how I would read "V8 access"), only that what is already exposed by Node.js in js.
So it just needs to be able to execute arbitrary JS, not "arbitrary V8 access", to potentially bypass this.
Both per the security model and (very likely) per the current state of things
lib,permission: add permission.drop
lib,permission: add permission.drop
github-actions commentedon Jul 20, 2026
This issue has been marked as stale due to 90 days of inactivity.
It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.
lib,permission: add permission.drop
lib,permission: add permission.drop