Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
19dad19
deps: float 15d7e79 from openssl
tniessen Jul 21, 2019
e334c1f
src: fix type name in comment
bnoordhuis Jun 20, 2019
386d5d7
lib: support min/max values in validateInteger()
cjihrig Jul 22, 2019
2262526
module: implement "exports" proposal for CommonJS
hybrist Jul 19, 2019
d0b1fb3
doc: api/stream.md typo from writeable to writable
imcotton Jul 23, 2019
e0e7763
crypto: increase maxmem range from 32 to 53 bits
tniessen Jul 21, 2019
a38fecd
tools: update certdata.txt
sam-github Jul 22, 2019
86f4c68
crypto: update root certificates
sam-github Jul 22, 2019
c0a0448
doc: fix type in NSS update instructions
sam-github Jul 22, 2019
24b9d29
build: `uname -m` is amd64 on freebsd, not x86_64
bnoordhuis Jul 22, 2019
3c30456
src : elevate v8 namespaces
HarshithaKP Jul 22, 2019
0667d0c
doc: add documentation for response.flushHeaders()
lpinca Jul 22, 2019
95b87ce
doc: claim NODE_MODULE_VERSION=76 for Electron 8
MarshallOfSound Jul 22, 2019
ae56a23
deps: backport b107214 from upstream V8
addaleax Jul 24, 2019
727ffe4
domain: use strong reference to domain while active
addaleax Jun 20, 2019
881e345
doc: describe why new Buffer() is problematic
sam-github Jul 23, 2019
860c0d8
n-api: add APIs for per-instance state management
Jul 15, 2019
454e879
doc: fix incorrect name in report docs
cjihrig Jul 24, 2019
e0951c8
report: loop over uv_cpu_info() results
cjihrig Jul 23, 2019
d3426ee
assert: avoid potentially misleading reference to object identity
addaleax Jul 23, 2019
b7c6ad5
crypto: add outputLength option to crypto.createHash
tniessen Jul 19, 2019
3a62202
crypto: fix handling of malicious getters (scrypt)
tniessen Jul 23, 2019
5d5c89a
policy: add dependencies map for resources
bmeck Jul 18, 2019
ffc7a00
doc: add documentation for stream.destroyed
ronag Jul 23, 2019
e6b3bfe
n-api: refactor a previous commit
Jul 18, 2019
cf071a0
stream: resolve perf regression introduced by V8 7.3
mcollina Jul 24, 2019
82f263d
build,tools: support building with Visual Studio 2019
targos Jul 20, 2019
f6051f9
test: specialize OOM check for AIX
sam-github Jul 24, 2019
8db43b1
src: move relative uptime init
Jul 24, 2019
c9c7256
http: reset parser.incoming when server response is finished
addaleax Jul 11, 2019
24b8f20
deps: remove backup files
AdamMajer Jul 26, 2019
9e7c662
build: ignore backup files
AdamMajer Jul 26, 2019
a7ef102
crypto: add null check to outputLength logic
cjihrig Jul 26, 2019
0b6a84a
test,report: relax CPU match requirements
addaleax Jul 28, 2019
84efadf
test, util: refactor isObject in test-util
RamirezAlex Jul 27, 2019
5533d48
doc: correct import statement
himself65 Jul 27, 2019
085eb48
doc: fixup esm resolver spec formatting
guybedford Jul 28, 2019
406c50c
src: read break_node_first_line from the inspect options
MarshallOfSound Jun 19, 2019
2142b6d
test: improve test-async-hooks-http-parser-destroy
Flarna Jun 16, 2019
b282c85
vm: increase code coverage of source_text_module.js
kball Jun 21, 2019
9b02f36
deps: dlloads node static linked executable
lal12 Jun 4, 2019
9dfa636
dgram: changed 'var' to 'let' and 'const'
mgochoa Jun 21, 2019
1b0d67b
src: fix OpenBSD build
devnexen Jun 22, 2019
d0d3149
http2: add constant to already destructured constants
dnalborczyk Jun 11, 2019
fa82cbc
http2: destructure constants from require call
dnalborczyk Jun 11, 2019
a28db5f
doc: add example of event close for child_process
ltciro Jun 21, 2019
32cf344
src: readlink("/proc/self/exe") -> uv_exename()
bnoordhuis Jun 21, 2019
a0f89a2
test: refactor test using assert instead of try/catch
juansb827 Jun 21, 2019
9b47f77
test: udpate test comment description
Angelfire Jun 21, 2019
048db38
benchmark: swap var for let in url benchmarks
RamirezAlex Jul 24, 2019
f2c1f36
benchmark: swap var for let in util benchmarks
RamirezAlex Jul 24, 2019
bbcf9f0
benchmark: swap var for let in buffer benchmarks
RamirezAlex Jul 26, 2019
cce2087
src: export v8.GetHeapCodeAndMetadataStatistics()
May 30, 2019
fb57bc4
build: do not mix spaces and tabs in Makefile
lpinca Jul 28, 2019
31aa33b
test: fix race in test-http2-origin
mildsunrise Jul 30, 2019
19070e4
test: fix nits in test/fixtures/tls-connect.js
lpinca Jul 28, 2019
25aa222
build: generate openssl config for BSD-x86
bnoordhuis Jul 22, 2019
3d51d30
src: large pages fix FreeBSD fix region size
devnexen Jul 17, 2019
470db47
build: remove support for s390 (but not s390x)
bnoordhuis Jul 28, 2019
391fe46
benchmark, http: refactor for code consistency
RamirezAlex Jul 21, 2019
464136f
lib: replace var with let in loaders.js
mbj36 Jun 5, 2019
43acce1
worker: handle calling terminate when kHandler is null
elyalvarado Jun 21, 2019
3e63429
doc: add example about emitter.emit in events documentation
felipedc09 Jun 21, 2019
b6e174b
test: use assert.throws() in test-require-json.js
alejandronanez Jun 21, 2019
d72b682
inspector: report all workers
eugeneo Jul 26, 2019
5f07f49
doc: revoke DEP0089
cjihrig Jul 29, 2019
d9084d2
module: unify package exports test for CJS and ESM
hybrist Jul 24, 2019
d601a0a
src: allow generic C++ callables in SetImmediate()
addaleax Jul 15, 2019
7c80963
doc: include "exports" resolver specification
guybedford Dec 11, 2018
c93df0c
n-api: refactoring napi_create_function testing
Jul 28, 2019
c42eb5d
test: refactoring test_error testing
himself65 Jul 30, 2019
efe9b97
test: refactor test-beforeexit-event-exit using mustNotCall
himself65 Jul 30, 2019
dcef7b8
build: include stubs in shared library
jeroen Jul 29, 2019
2236aff
module: exports error as MODULE_NOT_FOUND
guybedford Jul 31, 2019
c389526
test: add tests for spaces in folder names
PaulBags Jul 23, 2019
0ac6d28
doc: writableFinished is true before 'finish'
ronag Jul 23, 2019
f4abf17
doc: remove legacy mode deprecation in assert
Trott Jul 31, 2019
7d9eb17
http2: destroy when settingsFn throws an error
himself65 Jul 31, 2019
57f5d50
doc: fix sorting nit in sections of http.md
vsemozhetbyt Aug 2, 2019
4b91e4d
report: include network interfaces in report
cjihrig Jul 23, 2019
0f8f552
test: refactor test-fs-stat.js
Trott Aug 1, 2019
bdd442f
doc: describe NODE_OPTIONS interop w/cmd line opts
reasonablytall Aug 1, 2019
4a747f6
Revert "src: remove trace_sync_io_ from env"
ChALkeR Aug 1, 2019
3c52dbe
net: shallow copy option when create Server
himself65 Aug 1, 2019
02a50c3
doc: remove use of you
mhdawson Aug 1, 2019
1f82929
path: improve normalization performance
mscdex Aug 3, 2019
11470d5
deps: upgrade npm to 6.10.2
isaacs Jul 25, 2019
77d8f0c
2019-08-06, Version 12.8.0 (Current)
BridgeAR Aug 6, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
policy: add dependencies map for resources
Adds a "dependencies" field to resources in policy manifest files.
In order to ease development and testing while using manifests,
wildcard values for both "dependencies" and "integrity" have been
added using the boolean value "true" in the policy manifest.

PR-URL: #28767
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Jan Krems <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
Reviewed-By: Rich Trott <[email protected]>
  • Loading branch information
bmeck authored and targos committed Aug 2, 2019
commit 5d5c89a8f7ea7e0bbe69ccbe3bd052ca562e61dd
14 changes: 14 additions & 0 deletions doc/api/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -1430,6 +1430,13 @@ An attempt was made to load a resource, but the resource did not match the
integrity defined by the policy manifest. See the documentation for [policy]
manifests for more information.

<a id="ERR_MANIFEST_DEPENDENCY_MISSING"></a>
### ERR_MANIFEST_DEPENDENCY_MISSING

An attempt was made to load a resource, but the resource was not listed as a
dependency from the location that attempted to load it. See the documentation
for [policy] manifests for more information.

<a id="ERR_MANIFEST_INTEGRITY_MISMATCH"></a>
### ERR_MANIFEST_INTEGRITY_MISMATCH

Expand All @@ -1438,6 +1445,13 @@ entries for a resource which did not match each other. Update the manifest
entries to match in order to resolve this error. See the documentation for
[policy] manifests for more information.

<a id="ERR_MANIFEST_INVALID_RESOURCE_FIELD"></a>
### ERR_MANIFEST_INVALID_RESOURCE_FIELD

A policy manifest resource had an invalid value for one of its fields. Update
the manifest entry to match in order to resolve this error. See the
documentation for [policy] manifests for more information.

<a id="ERR_MANIFEST_PARSE_POLICY"></a>
### ERR_MANIFEST_PARSE_POLICY

Expand Down
78 changes: 76 additions & 2 deletions doc/api/policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ node --experimental-policy=policy.json app.js
The policy manifest will be used to enforce constraints on code loaded by
Node.js.

In order to mitigate tampering with policy files on disk, an integrity for
To mitigate tampering with policy files on disk, an integrity for
the policy file itself may be provided via `--policy-integrity`.
This allows running `node` and asserting the policy file contents
even if the file is changed on disk.
Expand Down Expand Up @@ -105,9 +105,83 @@ When loading resources the entire URL must match including search parameters
and hash fragment. `./a.js?b` will not be used when attempting to load
`./a.js` and vice versa.

In order to generate integrity strings, a script such as
To generate integrity strings, a script such as
`printf "sha384-$(cat checked.js | openssl dgst -sha384 -binary | base64)"`
can be used.

Integrity can be specified as the boolean value `true` to accept any
body for the resource which can be useful for local development. It is not
recommended in production since it would allow unexpected alteration of
resources to be considered valid.

### Dependency Redirection

An application may need to ship patched versions of modules or to prevent
modules from allowing all modules access to all other modules. Redirection
can be used by intercepting attempts to load the modules wishing to be
replaced.

```json
{
"builtins": [],
"resources": {
"./app/checked.js": {
"dependencies": {
"fs": true,
"os": "./app/node_modules/alt-os"
}
}
}
}
```

The dependencies are keyed by the requested string specifier and have values
of either `true` or a string pointing to a module that will be resolved.

The specifier string does not perform any searching and must match exactly
what is provided to the `require()`. Therefore, multiple specifiers may be
needed in the policy if `require()` uses multiple different strings to point
to the same module (such as excluding the extension).

If the value of the redirection is `true` the default searching algorithms will
be used to find the module.

If the value of the redirection is a string, it will be resolved relative to
the manifest and then immediately be used without searching.

Any specifier string that is `require()`ed and not listed in the dependencies
will result in an error according to the policy.

Redirection will not prevent access to APIs through means such as direct access
to `require.cache` and/or through `module.constructor` which allow access to
loading modules. Policy redirection only affect specifiers to `require()`.
Other means such as to prevent undesired access to APIs through variables are
necessary to lock down that path of loading modules.

A boolean value of `true` for the dependencies map can be specified to allow a
module to load any specifier without redirection. This can be useful for local
development and may have some valid usage in production, but should be used
only with care after auditing a module to ensure its behavior is valid.

#### Example: Patched Dependency

Since a dependency can be redirected, you can provide attenuated or modified
forms of dependencies as fits your application. For example, you could log
data about timing of function durations by wrapping the original:

```js
const original = require('fn');
module.exports = function fn(...args) {
console.time();
try {
return new.target ?
Reflect.construct(original, args) :
Reflect.apply(original, this, args);
} finally {
console.timeEnd();
}
};
```


[relative url string]: https://url.spec.whatwg.org/#relative-url-with-fragment-string
6 changes: 6 additions & 0 deletions lib/internal/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -1028,9 +1028,15 @@ E('ERR_MANIFEST_ASSERT_INTEGRITY',
}
return msg;
}, Error);
E('ERR_MANIFEST_DEPENDENCY_MISSING',
'Manifest resource %s does not list %s as a dependency specifier',
Error);
E('ERR_MANIFEST_INTEGRITY_MISMATCH',
'Manifest resource %s has multiple entries but integrity lists do not match',
SyntaxError);
E('ERR_MANIFEST_INVALID_RESOURCE_FIELD',
'Manifest resource %s has invalid property value for %s',
TypeError);
E('ERR_MANIFEST_TDZ', 'Manifest initialization has not yet run', Error);
E('ERR_MANIFEST_UNKNOWN_ONERROR',
'Manifest specified unknown error behavior "%s".',
Expand Down
62 changes: 58 additions & 4 deletions lib/internal/modules/cjs/helpers.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,72 @@
'use strict';

const { Object } = primordials;
const {
ERR_MANIFEST_DEPENDENCY_MISSING,
ERR_UNKNOWN_BUILTIN_MODULE
} = require('internal/errors').codes;
const { NativeModule } = require('internal/bootstrap/loaders');
const { getOptionValue } = require('internal/options');
const experimentalModules = getOptionValue('--experimental-modules');

const { validateString } = require('internal/validators');
const path = require('path');
const { pathToFileURL } = require('internal/url');
const { pathToFileURL, fileURLToPath } = require('internal/url');
const { URL } = require('url');

const debug = require('internal/util/debuglog').debuglog('module');

function loadNativeModule(filename, request, experimentalModules) {
const mod = NativeModule.map.get(filename);
if (mod) {
debug('load native module %s', request);
mod.compileForPublicLoader(experimentalModules);
return mod;
}
}

// Invoke with makeRequireFunction(module) where |module| is the Module object
// to use as the context for the require() function.
function makeRequireFunction(mod) {
// Use redirects to set up a mapping from a policy and restrict dependencies
function makeRequireFunction(mod, redirects) {
const Module = mod.constructor;

function require(path) {
return mod.require(path);
let require;
if (redirects) {
const { map, reaction } = redirects;
const id = mod.filename || mod.id;
require = function require(path) {
let missing = true;
if (map === true) {
missing = false;
} else if (map.has(path)) {
const redirect = map.get(path);
if (redirect === true) {
missing = false;
} else if (typeof redirect === 'string') {
const parsed = new URL(redirect);
if (parsed.protocol === 'node:') {
const specifier = parsed.pathname;
const mod = loadNativeModule(
specifier,
redirect,
experimentalModules);
if (mod && mod.canBeRequiredByUsers) return mod.exports;
throw new ERR_UNKNOWN_BUILTIN_MODULE(specifier);
} else if (parsed.protocol === 'file:') {
return mod.require(fileURLToPath(parsed));
}
}
}
if (missing) {
reaction(new ERR_MANIFEST_DEPENDENCY_MISSING(id, path));
}
return mod.require(path);
};
} else {
require = function require(path) {
return mod.require(path);
};
}

function resolve(request, options) {
Expand Down Expand Up @@ -134,6 +187,7 @@ function normalizeReferrerURL(referrer) {
module.exports = {
addBuiltinLibsToObject,
builtinLibs,
loadNativeModule,
makeRequireFunction,
normalizeReferrerURL,
stripBOM,
Expand Down
19 changes: 10 additions & 9 deletions lib/internal/modules/cjs/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ const {
makeRequireFunction,
normalizeReferrerURL,
stripBOM,
stripShebang
stripShebang,
loadNativeModule
} = require('internal/modules/cjs/helpers');
const { getOptionValue } = require('internal/options');
const preserveSymlinks = getOptionValue('--preserve-symlinks');
Expand Down Expand Up @@ -619,11 +620,8 @@ Module._load = function(request, parent, isMain) {
return cachedModule.exports;
}

const mod = NativeModule.map.get(filename);
if (mod && mod.canBeRequiredByUsers) {
debug('load native module %s', request);
return mod.compileForPublicLoader(experimentalModules);
}
const mod = loadNativeModule(filename, request, experimentalModules);
if (mod && mod.canBeRequiredByUsers) return mod.exports;

// Don't call updateChildren(), Module constructor already does.
const module = new Module(filename, parent);
Expand Down Expand Up @@ -784,8 +782,11 @@ let hasPausedEntry = false;
// the file.
// Returns exception, if any.
Module.prototype._compile = function(content, filename) {
let moduleURL;
let redirects;
if (manifest) {
const moduleURL = pathToFileURL(filename);
moduleURL = pathToFileURL(filename);
redirects = manifest.getRedirects(moduleURL);
manifest.assertIntegrity(moduleURL, content);
}

Expand Down Expand Up @@ -851,7 +852,7 @@ Module.prototype._compile = function(content, filename) {
}
}
const dirname = path.dirname(filename);
const require = makeRequireFunction(this);
const require = makeRequireFunction(this, redirects);
var result;
const exports = this.exports;
const thisValue = exports;
Expand Down Expand Up @@ -940,7 +941,7 @@ function createRequireFromPath(filename) {
m.filename = proxyPath;

m.paths = Module._nodeModulePaths(m.path);
return makeRequireFunction(m);
return makeRequireFunction(m, null);
}

Module.createRequireFromPath = createRequireFromPath;
Expand Down
7 changes: 3 additions & 4 deletions lib/internal/modules/esm/translators.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ const {
StringPrototype
} = primordials;

const { NativeModule } = require('internal/bootstrap/loaders');
const {
stripShebang,
stripBOM
stripBOM,
loadNativeModule
} = require('internal/modules/cjs/helpers');
const CJSModule = require('internal/modules/cjs/loader');
const internalURLModule = require('internal/url');
Expand Down Expand Up @@ -94,11 +94,10 @@ translators.set('builtin', async function builtinStrategy(url) {
debug(`Translating BuiltinModule ${url}`);
// Slice 'node:' scheme
const id = url.slice(5);
const module = NativeModule.map.get(id);
const module = loadNativeModule(id, url, true);
if (!module) {
throw new ERR_UNKNOWN_BUILTIN_MODULE(id);
}
module.compileForPublicLoader(true);
return createDynamicModule(
[], [...module.exportKeys, 'default'], url, (reflect) => {
debug(`Loading BuiltinModule ${url}`);
Expand Down
Loading