The current documentation clearly states that createCipher() and
createDecipher() should not be used with ciphers in counter mode, but
(1) this is an understatement, and (2) these functions are
(semantically) insecure for ciphers in any other supported block cipher
mode as well.
Semantic security requires IND-CPA, but a deterministic cipher with
fixed key and IV, such as those generated by these functions, does not
fulfill IND-CPA.
Are there justified use cases for createCipher() and createDecipher()?
Yes and no. The only case in which these functions can be used in a
semantically secure manner arises only when the password argument is
not actually a password but rather a random or pseudo-random sequence
that is unpredictable and that is never reused (e.g., securely derived
from a password with a proper salt). Insofar, it is possible to use
these APIs without immediately creating a vulnerability. However,
- any application that manages to fulfill this requirement should also
be able to fulfill the similar requirements of crypto.createCipheriv()
and those of crypto.createDecipheriv(), which give much more control
over key and initialization vector, and
- the MD5-based key derivation step generally does not help and might
even reduce the overall security due to its many weaknesses.
Refs: https://github.com/nodejs/node/pull/13821
Refs: https://github.com/nodejs/node/pull/19343
Refs: https://github.com/nodejs/node/pull/22089
PR-URL: https://github.com/nodejs/node/pull/44538
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Explicitly document the attribute `Script.cachedDataRejected` in a
dedicated section.
Removes the documented option `produceCachedData` and the description
of `cachedDataRejected` in `vm.runInContext`, `vm.runInNewContext`,
and `vm.runInThisContext` as the created `vm.Script` instance is not
accessible from userland in these methods.
PR-URL: https://github.com/nodejs/node/pull/44451
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
If `--max-old-space-size` is passed on the command line, it takes
precedence over `resourceLimits.maxOldSpaceSizeMb` passed to the worker
thread. IMO this is a bug, but seems unlikely to change(?), so let's
start by documenting it. See the attached issue for more details.
Refs: https://github.com/nodejs/node/issues/43991
PR-URL: https://github.com/nodejs/node/pull/43992
Reviewed-By: James M Snell <jasnell@gmail.com>
Add WebPerf API `performance.setResourceTimingBufferSize` and event
`'resourcetimingbufferfull'` support.
The resource timing entries are added to the global performance
timeline buffer automatically when using fetch. If users are not
proactively cleaning these events, it can grow without limit. Apply
the https://www.w3.org/TR/timing-entrytypes-registry/ default
resource timing buffer max size so that the buffer can be limited
to not grow indefinitely.
PR-URL: https://github.com/nodejs/node/pull/44220
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
To comply with RFC 7301, make TLS servers send a fatal alert during the
TLS handshake if both the client and the server are configured to use
ALPN and if the server does not support any of the protocols advertised
by the client.
This affects HTTP/2 servers. Until now, applications could intercept the
'unknownProtocol' event when the client either did not advertise any
protocols or if the list of protocols advertised by the client did not
include HTTP/2 (or HTTP/1.1 if allowHTTP1 was true). With this change,
only the first case can be handled, and the 'unknownProtocol' event will
not be emitted in the second case because the TLS handshake fails and no
secure connection is established.
PR-URL: https://github.com/nodejs/node/pull/44031
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
This patch stores the metadata about the Node.js binary
into the SnapshotData and adds fields denoting how the
snapshot was generated, on what platform it was
generated as well as the V8 cached data version flag.
Instead of simply crashing when the metadata doesn't
match, Node.js now prints an error message and exit with
1 for the customized snapshot, or ignore the snapshot
and start from scratch if it's the default one.
PR-URL: https://github.com/nodejs/node/pull/44132
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
The term "native module" dates back to some of the oldest code
in the code base. Within the context of Node.js core it usually
refers to modules that are native to Node.js (e.g. fs, http),
but it can cause confusion for people who don't work on this
part of the code base, as "native module" can also refer to
native addons - which is even the case in some of the API
docs and error messages.
This patch tries to make the usage of these terms more consistent.
Now within the context of Node.js core:
- JavaScript scripts that are built-in to Node.js are now referred
to as "built-in(s)". If they are available as modules,
they can also be referred to as "built-in module(s)".
- Dynamically-linked shared objects that are loaded into
the Node.js processes are referred to as "addons".
We will try to avoid using the term "native modules" because it could
be ambiguous.
Changes in this patch:
File names:
- node_native_module.h -> node_builtins.h,
- node_native_module.cc -> node_builtins.cc
C++ binding names:
- `native_module` -> `builtins`
`node::Environment`:
- `native_modules_without_cache` -> `builtins_without_cache`
- `native_modules_with_cache` -> `builtins_with_cache`
- `native_modules_in_snapshot` -> `builtins_in_cache`
- `native_module_require` -> `builtin_module_require`
`node::EnvSerializeInfo`:
- `native_modules` -> `builtins
`node::native_module::NativeModuleLoader`:
- `native_module` namespace -> `builtins` namespace
- `NativeModuleLoader` -> `BuiltinLoader`
- `NativeModuleRecordMap` -> `BuiltinSourceMap`
- `NativeModuleCacheMap` -> `BuiltinCodeCacheMap`
- `ModuleIds` -> `BuiltinIds`
- `ModuleCategories` -> `BuiltinCategories`
- `LoadBuiltinModuleSource` -> `LoadBuiltinSource`
`loader.js`:
- `NativeModule` -> `BuiltinModule` (the `NativeModule` name used in
`process.moduleLoadList` is kept for compatibility)
And other clarifications in the documentation and comments.
PR-URL: https://github.com/nodejs/node/pull/44135
Fixes: https://github.com/nodejs/node/issues/44036
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Michael Dawson <midawson@redhat.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Jan Krems <jan.krems@gmail.com>
So far, process initialization has been a bit all over the place
in Node.js. `InitializeNodeWithArgs()` is our main public API
for this, but inclusion of items in it vs. `InitializeOncePerProcess()`
and `PlatformInit()` has been random at best. Likewise,
some pieces of initialization have been guarded by
`NODE_SHARED_MODE`, but also fairly randomly and without
any meaningful connection to shared library usage.
This leaves embedders in a position to cherry-pick some of
the initialization code into their own code to make their
application behave like typical Node.js applications to the
degree to which they desire it.
Electron takes an alternative route and makes direct use of
`InitializeOncePerProcess()` already while it is a private
API, with a `TODO` to add it to the public API in Node.js.
This commit addresses that `TODO`, and `TODO`s around the
`NODE_SHARED_MODE` usage. Specifically:
- `InitializeOncePerProcess()` and `TearDownOncePerProcess()`
are added to the public API.
- The `flags` option of these functions are merged with the
`flags` option for `InitializeNodeWithArgs()`, since they
essentially share the same semantics.
- The return value of the function is made an abstract class,
rather than a struct, for easier API/ABI stability.
- Initialization code from `main()` is brought into these
functions (since that makes sense in general).
- Add a `TODO` for turning `InitializeNodeWithArgs()` into
a small wrapper around `InitializeOncePerProcess()` and
eventually removing it (at least one major release cycle
each, presumably).
- Remove `NODE_SHARED_MODE` guards and replace them with
runtime options.
PR-URL: https://github.com/nodejs/node/pull/44121
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Michael Dawson <midawson@redhat.com>
This patch introduces `--build-snapshot` and `--snapshot-blob` options
for creating and using user land snapshots.
For the initial iteration, user land CJS modules and ESM are not yet
supported in the snapshot, so only one single file can be snapshotted
(users can bundle their applications into a single script with their
bundler of choice to build a snapshot though).
A subset of builtins should already work, and support for more builtins
are being added. This PR includes tests checking that the TypeScript
compiler and the marked markdown renderer (and the builtins they use)
can be snapshotted and deserialized.
To generate a snapshot using `snapshot.js` as entry point and write the
snapshot blob to `snapshot.blob`:
```
$ echo "globalThis.foo = 'I am from the snapshot'" > snapshot.js
$ node --snapshot-blob snapshot.blob --build-snapshot snapshot.js
```
To restore application state from `snapshot.blob`, with `index.js` as
the entry point script for the deserialized application:
```
$ echo "console.log(globalThis.foo)" > index.js
$ node --snapshot-blob snapshot.blob index.js
I am from the snapshot
```
Users can also use the `v8.startupSnapshot` API to specify an entry
point at snapshot building time, thus avoiding the need of an additional
entry script at deserialization time:
```
$ echo "require('v8').startupSnapshot.setDeserializeMainFunction(() => console.log('I am from the snapshot'))" > snapshot.js
$ node --snapshot-blob snapshot.blob --build-snapshot snapshot.js
$ node --snapshot-blob snapshot.blob
I am from the snapshot
```
Note that this patch only adds functionality to the `node` executable
for building run-time user-land snapshots, the generated snapshot is
stored into a separate file on disk. Building a single binary with both
Node.js and an embedded snapshot has already been possible with the
`--node-snapshot-main` option to the `configure` script if the user
compiles Node.js from source. It would be a different task to enable the
`node` executable to produce a single binary that contains both Node.js
and an embedded snapshot without building Node.js from source, which
should be layered on top of the SEA (Single Executable Apps) initiative.
Known limitations/bugs that are being fixed in the upstream:
- V8 hits a DCHECK when deserializing certain mutated globals, e.g.
`Error.stackTraceLimit` (it should work fine in the release build,
however): https://chromium-review.googlesource.com/c/v8/v8/+/3319481
- Layout of V8's read-only heap can be inconsistent after
deserialization, resulting in memory corruption:
https://bugs.chromium.org/p/v8/issues/detail?id=12921
PR-URL: https://github.com/nodejs/node/pull/38905
Refs: https://github.com/nodejs/node/issues/35711
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>