mirror of
https://github.com/nodejs/node.git
synced 2025-08-18 07:08:50 +02:00
policy: disable process.binding() when enabled
process.binding() can be used to trivially bypass restrictions imposed through a policy. Since the function is deprecated already, simply replace it with a stub when a policy is being enabled. Fixes: https://hackerone.com/bugs?report_id=1946470 PR-URL: https://github.com/nodejs-private/node-private/pull/397 Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com> CVE-ID: CVE-2023-32559
This commit is contained in:
parent
4fdf70f9ab
commit
4aa0eff787
6 changed files with 65 additions and 0 deletions
|
@ -2215,6 +2215,9 @@ Type: Documentation-only (supports [`--pending-deprecation`][])
|
|||
|
||||
`process.binding()` is for use by Node.js internal code only.
|
||||
|
||||
While `process.binding()` has not reached End-of-Life status in general, it is
|
||||
unavailable when [policies][] are enabled.
|
||||
|
||||
### DEP0112: `dgram` private APIs
|
||||
|
||||
<!-- YAML
|
||||
|
@ -3532,6 +3535,7 @@ Consider using alternatives such as the [`mock`][] helper function.
|
|||
[from_string_encoding]: buffer.md#static-method-bufferfromstring-encoding
|
||||
[legacy URL API]: url.md#legacy-url-api
|
||||
[legacy `urlObject`]: url.md#legacy-urlobject
|
||||
[policies]: permissions.md#policies
|
||||
[static methods of `crypto.Certificate()`]: crypto.md#class-certificate
|
||||
[subpath exports]: packages.md#subpath-exports
|
||||
[subpath imports]: packages.md#subpath-imports
|
||||
|
|
|
@ -957,6 +957,9 @@ module.exports = {
|
|||
//
|
||||
// Note: Node.js specific errors must begin with the prefix ERR_
|
||||
|
||||
E('ERR_ACCESS_DENIED',
|
||||
'Access to this API has been restricted. Permission: %s',
|
||||
Error);
|
||||
E('ERR_AMBIGUOUS_ARGUMENT', 'The "%s" argument is ambiguous. %s', TypeError);
|
||||
E('ERR_ARG_NOT_ITERABLE', '%s must be iterable', TypeError);
|
||||
E('ERR_ASSERTION', '%s', Error);
|
||||
|
|
|
@ -7,6 +7,7 @@ const {
|
|||
} = primordials;
|
||||
|
||||
const {
|
||||
ERR_ACCESS_DENIED,
|
||||
ERR_MANIFEST_TDZ,
|
||||
} = require('internal/errors').codes;
|
||||
const { Manifest } = require('internal/policy/manifest');
|
||||
|
@ -32,6 +33,15 @@ module.exports = ObjectFreeze({
|
|||
return o;
|
||||
});
|
||||
manifest = new Manifest(json, url);
|
||||
|
||||
// process.binding() is deprecated (DEP0111) and trivially allows bypassing
|
||||
// policies, so if policies are enabled, make this API unavailable.
|
||||
process.binding = function binding(_module) {
|
||||
throw new ERR_ACCESS_DENIED('process.binding');
|
||||
};
|
||||
process._linkedBinding = function _linkedBinding(_module) {
|
||||
throw new ERR_ACCESS_DENIED('process._linkedBinding');
|
||||
};
|
||||
},
|
||||
|
||||
get manifest() {
|
||||
|
|
10
test/fixtures/policy/process-binding/app.js
vendored
Normal file
10
test/fixtures/policy/process-binding/app.js
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
|
||||
assert.throws(() => { process.binding(); }, {
|
||||
code: 'ERR_ACCESS_DENIED'
|
||||
});
|
||||
assert.throws(() => { process._linkedBinding(); }, {
|
||||
code: 'ERR_ACCESS_DENIED'
|
||||
});
|
10
test/fixtures/policy/process-binding/policy.json
vendored
Normal file
10
test/fixtures/policy/process-binding/policy.json
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"resources": {
|
||||
"./app.js": {
|
||||
"integrity": true,
|
||||
"dependencies": {
|
||||
"assert": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
28
test/parallel/test-policy-process-binding.js
Normal file
28
test/parallel/test-policy-process-binding.js
Normal file
|
@ -0,0 +1,28 @@
|
|||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
common.requireNoPackageJSONAbove();
|
||||
|
||||
if (!common.hasCrypto)
|
||||
common.skip('missing crypto');
|
||||
|
||||
const fixtures = require('../common/fixtures');
|
||||
|
||||
const assert = require('node:assert');
|
||||
const { spawnSync } = require('node:child_process');
|
||||
|
||||
const dep = fixtures.path('policy', 'process-binding', 'app.js');
|
||||
const depPolicy = fixtures.path(
|
||||
'policy',
|
||||
'process-binding',
|
||||
'policy.json');
|
||||
const { status } = spawnSync(
|
||||
process.execPath,
|
||||
[
|
||||
'--experimental-policy', depPolicy, dep,
|
||||
],
|
||||
{
|
||||
stdio: 'inherit'
|
||||
},
|
||||
);
|
||||
assert.strictEqual(status, 0);
|
Loading…
Add table
Add a link
Reference in a new issue