GeezerVison is showing github.com — lib: enable global WebCrypto by default · nodejs/node@6de2673
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: .eslintrc.js +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -322,6 +322,7 @@ module.exports = { | 322 | 322 | CompressionStream: 'readable', | 323 | 323 | CountQueuingStrategy: 'readable', | 324 | 324 | CustomEvent: 'readable', | | 325 | + crypto: 'readable', | 325 | 326 | Crypto: 'readable', | 326 | 327 | CryptoKey: 'readable', | 327 | 328 | DecompressionStream: 'readable', | |
Collapse file Copy file name to clipboardExpand all lines: doc/api/cli.md +9-11Lines changed: 9 additions & 11 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
@@ -351,16 +351,6 @@ added: | 351 | 351 |
| 352 | 352 | Expose the [CustomEvent Web API][] on the global scope. | 353 | 353 |
| 354 | | -### `--experimental-global-webcrypto` | 355 | | - | 356 | | -<!-- YAML | 357 | | -added: | 358 | | - - v17.6.0 | 359 | | - - v16.15.0 | 360 | | ---> | 361 | | - | 362 | | -Expose the [Web Crypto API][] on the global scope. | 363 | | - | 364 | 354 | ### `--experimental-import-meta-resolve` | 365 | 355 |
| 366 | 356 | <!-- YAML | @@ -413,6 +403,14 @@ added: v18.0.0 | 413 | 403 |
| 414 | 404 | Disable experimental support for the [Fetch API][]. | 415 | 405 |
| | 406 | +### `--no-experimental-global-webcrypto` | | 407 | + | | 408 | +<!-- YAML | | 409 | +added: REPLACEME | | 410 | +--> | | 411 | + | | 412 | +Disable exposition of [Web Crypto API][] on the global scope. | | 413 | + | 416 | 414 | ### `--no-experimental-repl-await` | 417 | 415 |
| 418 | 416 | <!-- YAML | @@ -1839,7 +1837,6 @@ Node.js options that are allowed are: | 1839 | 1837 | * `--enable-source-maps` | 1840 | 1838 | * `--experimental-abortcontroller` | 1841 | 1839 | * `--experimental-global-customevent` | 1842 | | -* `--experimental-global-webcrypto` | 1843 | 1840 | * `--experimental-import-meta-resolve` | 1844 | 1841 | * `--experimental-json-modules` | 1845 | 1842 | * `--experimental-loader` | @@ -1872,6 +1869,7 @@ Node.js options that are allowed are: | 1872 | 1869 | * `--no-addons` | 1873 | 1870 | * `--no-deprecation` | 1874 | 1871 | * `--no-experimental-fetch` | | 1872 | +* `--no-experimental-global-webcrypto` | 1875 | 1873 | * `--no-experimental-repl-await` | 1876 | 1874 | * `--no-extra-info-on-fatal-exception` | 1877 | 1875 | * `--no-force-async-hooks-checks` | |
Collapse file Copy file name to clipboardExpand all lines: doc/api/globals.md +25-9Lines changed: 25 additions & 9 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
@@ -345,10 +345,14 @@ A browser-compatible implementation of [`CountQueuingStrategy`][]. | 345 | 345 | added: | 346 | 346 | - v17.6.0 | 347 | 347 | - v16.15.0 | | 348 | +changes: | | 349 | + - version: REPLACEME | | 350 | + pr-url: https://github.com/nodejs/node/pull/42083 | | 351 | + description: No longer behind `--experimental-global-webcrypto` CLI flag. | 348 | 352 | --> | 349 | 353 |
| 350 | | -> Stability: 1 - Experimental. Enable this API with the | 351 | | -> [`--experimental-global-webcrypto`][] CLI flag. | | 354 | +> Stability: 1 - Experimental. Disable this API with the | | 355 | +> [`--no-experimental-global-webcrypto`][] CLI flag. | 352 | 356 |
| 353 | 357 | A browser-compatible implementation of {Crypto}. This global is available | 354 | 358 | only if the Node.js binary was compiled with including support for the | @@ -360,10 +364,14 @@ only if the Node.js binary was compiled with including support for the | 360 | 364 | added: | 361 | 365 | - v17.6.0 | 362 | 366 | - v16.15.0 | | 367 | +changes: | | 368 | + - version: REPLACEME | | 369 | + pr-url: https://github.com/nodejs/node/pull/42083 | | 370 | + description: No longer behind `--experimental-global-webcrypto` CLI flag. | 363 | 371 | --> | 364 | 372 |
| 365 | | -> Stability: 1 - Experimental. Enable this API with the | 366 | | -> [`--experimental-global-webcrypto`][] CLI flag. | | 373 | +> Stability: 1 - Experimental. Disable this API with the | | 374 | +> [`--no-experimental-global-webcrypto`][] CLI flag. | 367 | 375 |
| 368 | 376 | A browser-compatible implementation of the [Web Crypto API][]. | 369 | 377 |
| @@ -373,10 +381,14 @@ A browser-compatible implementation of the [Web Crypto API][]. | 373 | 381 | added: | 374 | 382 | - v17.6.0 | 375 | 383 | - v16.15.0 | | 384 | +changes: | | 385 | + - version: REPLACEME | | 386 | + pr-url: https://github.com/nodejs/node/pull/42083 | | 387 | + description: No longer behind `--experimental-global-webcrypto` CLI flag. | 376 | 388 | --> | 377 | 389 |
| 378 | | -> Stability: 1 - Experimental. Enable this API with the | 379 | | -> [`--experimental-global-webcrypto`][] CLI flag. | | 390 | +> Stability: 1 - Experimental. Disable this API with the | | 391 | +> [`--no-experimental-global-webcrypto`][] CLI flag. | 380 | 392 |
| 381 | 393 | A browser-compatible implementation of {CryptoKey}. This global is available | 382 | 394 | only if the Node.js binary was compiled with including support for the | @@ -725,10 +737,14 @@ The WHATWG [`structuredClone`][] method. | 725 | 737 | added: | 726 | 738 | - v17.6.0 | 727 | 739 | - v16.15.0 | | 740 | +changes: | | 741 | + - version: REPLACEME | | 742 | + pr-url: https://github.com/nodejs/node/pull/42083 | | 743 | + description: No longer behind `--experimental-global-webcrypto` CLI flag. | 728 | 744 | --> | 729 | 745 |
| 730 | | -> Stability: 1 - Experimental. Enable this API with the | 731 | | -> [`--experimental-global-webcrypto`][] CLI flag. | | 746 | +> Stability: 1 - Experimental. Disable this API with the | | 747 | +> [`--no-experimental-global-webcrypto`][] CLI flag. | 732 | 748 |
| 733 | 749 | A browser-compatible implementation of {SubtleCrypto}. This global is available | 734 | 750 | only if the Node.js binary was compiled with including support for the | @@ -870,8 +886,8 @@ A browser-compatible implementation of [`WritableStreamDefaultWriter`][]. | 870 | 886 |
| 871 | 887 | [Web Crypto API]: webcrypto.md | 872 | 888 | [`--experimental-global-customevent`]: cli.md#--experimental-global-customevent | 873 | | -[`--experimental-global-webcrypto`]: cli.md#--experimental-global-webcrypto | 874 | 889 | [`--no-experimental-fetch`]: cli.md#--no-experimental-fetch | | 890 | +[`--no-experimental-global-webcrypto`]: cli.md#--no-experimental-global-webcrypto | 875 | 891 | [`AbortController`]: https://developer.mozilla.org/en-US/docs/Web/API/AbortController | 876 | 892 | [`ByteLengthQueuingStrategy`]: webstreams.md#class-bytelengthqueuingstrategy | 877 | 893 | [`CompressionStream`]: webstreams.md#class-compressionstream | |
Collapse file Copy file name to clipboardExpand all lines: doc/node.1 +3Lines changed: 3 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -165,6 +165,9 @@ Use this flag to enable ShadowRealm support. | 165 | 165 | .It Fl -no-experimental-fetch | 166 | 166 | Disable experimental support for the Fetch API. | 167 | 167 | . | | 168 | +.It Fl -no-experimental-global-webcrypto | | 169 | +Disable exposition of the Web Crypto API on the global scope. | | 170 | +. | 168 | 171 | .It Fl -no-experimental-repl-await | 169 | 172 | Disable top-level await keyword support in REPL. | 170 | 173 | . | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/main/eval_string.js +26-2Lines changed: 26 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 4 | 4 | // `--interactive`. | 5 | 5 |
| 6 | 6 | const { | | 7 | + ObjectDefineProperty, | | 8 | + RegExpPrototypeExec, | 7 | 9 | globalThis, | 8 | 10 | } = primordials; | 9 | 11 |
| @@ -25,9 +27,31 @@ const print = getOptionValue('--print'); | 25 | 27 | const loadESM = getOptionValue('--import').length > 0; | 26 | 28 | if (getOptionValue('--input-type') === 'module') | 27 | 29 | evalModule(source, print); | 28 | | -else | | 30 | +else { | | 31 | + // For backward compatibility, we want the identifier crypto to be the | | 32 | + // `node:crypto` module rather than WebCrypto. | | 33 | + const isUsingCryptoIdentifier = | | 34 | + getOptionValue('--experimental-global-webcrypto') && | | 35 | + RegExpPrototypeExec(/\bcrypto\b/, source) !== null; | | 36 | + const shouldDefineCrypto = isUsingCryptoIdentifier && internalBinding('config').hasOpenSSL; | | 37 | + | | 38 | + if (isUsingCryptoIdentifier && !shouldDefineCrypto) { | | 39 | + // This is taken from `addBuiltinLibsToObject`. | | 40 | + const object = globalThis; | | 41 | + const name = 'crypto'; | | 42 | + const setReal = (val) => { | | 43 | + // Deleting the property before re-assigning it disables the | | 44 | + // getter/setter mechanism. | | 45 | + delete object[name]; | | 46 | + object[name] = val; | | 47 | + }; | | 48 | + ObjectDefineProperty(object, name, { __proto__: null, set: setReal }); | | 49 | + } | 29 | 50 | evalScript('[eval]', | 30 | | - source, | | 51 | + shouldDefineCrypto ? ( | | 52 | + print ? `let crypto=require("node:crypto");{${source}}` : `(crypto=>{{${source}}})(require('node:crypto'))` | | 53 | + ) : source, | 31 | 54 | getOptionValue('--inspect-brk'), | 32 | 55 | print, | 33 | 56 | loadESM); | | 57 | +} |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/process/pre_execution.js +17-10Lines changed: 17 additions & 10 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -25,6 +25,7 @@ const { | 25 | 25 |
| 26 | 26 | const { | 27 | 27 | ERR_MANIFEST_ASSERT_INTEGRITY, | | 28 | + ERR_NO_CRYPTO, | 28 | 29 | } = require('internal/errors').codes; | 29 | 30 | const assert = require('internal/assert'); | 30 | 31 |
| @@ -247,23 +248,29 @@ function setupFetch() { | 247 | 248 | // removed. | 248 | 249 | function setupWebCrypto() { | 249 | 250 | if (process.config.variables.node_no_browser_globals || | 250 | | - !getOptionValue('--experimental-global-webcrypto')) { | | 251 | + getOptionValue('--no-experimental-global-webcrypto')) { | 251 | 252 | return; | 252 | 253 | } | 253 | 254 |
| 254 | | - let webcrypto; | 255 | | - ObjectDefineProperty(globalThis, 'crypto', | 256 | | - { __proto__: null, ...ObjectGetOwnPropertyDescriptor({ | 257 | | - get crypto() { | 258 | | - webcrypto ??= require('internal/crypto/webcrypto'); | 259 | | - return webcrypto.crypto; | 260 | | - } | 261 | | - }, 'crypto') }); | 262 | 255 | if (internalBinding('config').hasOpenSSL) { | 263 | | - webcrypto ??= require('internal/crypto/webcrypto'); | | 256 | + const webcrypto = require('internal/crypto/webcrypto'); | | 257 | + ObjectDefineProperty(globalThis, 'crypto', | | 258 | + { __proto__: null, ...ObjectGetOwnPropertyDescriptor({ | | 259 | + get crypto() { | | 260 | + return webcrypto.crypto; | | 261 | + } | | 262 | + }, 'crypto') }); | 264 | 263 | exposeInterface(globalThis, 'Crypto', webcrypto.Crypto); | 265 | 264 | exposeInterface(globalThis, 'CryptoKey', webcrypto.CryptoKey); | 266 | 265 | exposeInterface(globalThis, 'SubtleCrypto', webcrypto.SubtleCrypto); | | 266 | + } else { | | 267 | + ObjectDefineProperty(globalThis, 'crypto', | | 268 | + { __proto__: null, ...ObjectGetOwnPropertyDescriptor({ | | 269 | + get crypto() { | | 270 | + throw new ERR_NO_CRYPTO(); | | 271 | + } | | 272 | + }, 'crypto') }); | | 273 | + | 267 | 274 | } | 268 | 275 | } | 269 | 276 |
| |
Collapse file Copy file name to clipboardExpand all lines: src/node_options.cc +2-1Lines changed: 2 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -370,7 +370,8 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() { | 370 | 370 | AddOption("--experimental-global-webcrypto", | 371 | 371 | "expose experimental Web Crypto API on the global scope", | 372 | 372 | &EnvironmentOptions::experimental_global_web_crypto, | 373 | | - kAllowedInEnvironment); | | 373 | + kAllowedInEnvironment, | | 374 | + true); | 374 | 375 | AddOption("--experimental-json-modules", "", NoOp{}, kAllowedInEnvironment); | 375 | 376 | AddOption("--experimental-loader", | 376 | 377 | "use the specified module as a custom loader", | |
Collapse file Copy file name to clipboardExpand all lines: src/node_options.h +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -110,7 +110,7 @@ class EnvironmentOptions : public Options { | 110 | 110 | bool enable_source_maps = false; | 111 | 111 | bool experimental_fetch = true; | 112 | 112 | bool experimental_global_customevent = false; | 113 | | - bool experimental_global_web_crypto = false; | | 113 | + bool experimental_global_web_crypto = true; | 114 | 114 | bool experimental_https_modules = false; | 115 | 115 | std::string experimental_specifier_resolution; | 116 | 116 | bool experimental_wasm_modules = false; | |
Collapse file Copy file name to clipboardExpand all lines: test/common/index.js +3-1Lines changed: 3 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -357,7 +357,9 @@ if (process.env.NODE_TEST_KNOWN_GLOBALS !== '0') { | 357 | 357 | const leaked = []; | 358 | 358 |
| 359 | 359 | for (const val in global) { | 360 | | - if (!knownGlobals.includes(global[val])) { | | 360 | + // globalThis.crypto is a getter that throws if Node.js was compiled | | 361 | + // without OpenSSL. | | 362 | + if (val !== 'crypto' && !knownGlobals.includes(global[val])) { | 361 | 363 | leaked.push(val); | 362 | 364 | } | 363 | 365 | } | |
Collapse file Copy file name to clipboard +21Lines changed: 21 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +'use strict'; | | 2 | + | | 3 | +const common = require('../common'); | | 4 | +const assert = require('assert'); | | 5 | + | | 6 | +if (!common.hasCrypto) { | | 7 | + assert.fail('When Node.js is compiled without OpenSSL, overriding the global ' + | | 8 | + 'crypto is allowed on string eval'); | | 9 | +} | | 10 | + | | 11 | +const child = require('child_process'); | | 12 | +const nodejs = `"${process.execPath}"`; | | 13 | + | | 14 | +// Trying to define a variable named `crypto` using `var` triggers an exception. | | 15 | + | | 16 | +child.exec( | | 17 | + `${nodejs} ` + | | 18 | + '-p "var crypto = {randomBytes:1};typeof crypto.randomBytes"', | | 19 | + common.mustSucceed((stdout) => { | | 20 | + assert.match(stdout, /^number/); | | 21 | + })); |
|