crypto: do not allow to call setFips from the worker thread

PR-URL: https://github.com/nodejs/node/pull/43624
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
This commit is contained in:
Sergey Petushkov 2022-07-08 12:50:24 +02:00 committed by GitHub
parent 1523a1817e
commit a1653ac715
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 19 additions and 2 deletions

View File

@ -37,6 +37,7 @@ assertCrypto();
const { const {
ERR_CRYPTO_FIPS_FORCED, ERR_CRYPTO_FIPS_FORCED,
ERR_WORKER_UNSUPPORTED_OPERATION,
} = require('internal/errors').codes; } = require('internal/errors').codes;
const constants = internalBinding('constants').crypto; const constants = internalBinding('constants').crypto;
const { getOptionValue } = require('internal/options'); const { getOptionValue } = require('internal/options');
@ -127,6 +128,12 @@ function lazyWebCrypto() {
return webcrypto; return webcrypto;
} }
let ownsProcessState;
function lazyOwnsProcessState() {
ownsProcessState ??= require('internal/worker').ownsProcessState;
return ownsProcessState;
}
// These helper functions are needed because the constructors can // These helper functions are needed because the constructors can
// use new, in which case V8 cannot inline the recursive constructor call // use new, in which case V8 cannot inline the recursive constructor call
function createHash(algorithm, options) { function createHash(algorithm, options) {
@ -250,6 +257,9 @@ function setFips(val) {
if (val) return; if (val) return;
throw new ERR_CRYPTO_FIPS_FORCED(); throw new ERR_CRYPTO_FIPS_FORCED();
} else { } else {
if (!lazyOwnsProcessState()) {
throw new ERR_WORKER_UNSUPPORTED_OPERATION('Calling crypto.setFips()');
}
setFipsCrypto(val); setFipsCrypto(val);
} }
} }

View File

@ -218,8 +218,7 @@ void SetFipsCrypto(const FunctionCallbackInfo<Value>& args) {
CHECK(!per_process::cli_options->force_fips_crypto); CHECK(!per_process::cli_options->force_fips_crypto);
Environment* env = Environment::GetCurrent(args); Environment* env = Environment::GetCurrent(args);
// TODO(addaleax): This should not be possible to set from worker threads. CHECK(env->owns_process_state());
// CHECK(env->owns_process_state());
bool enable = args[0]->BooleanValue(env->isolate()); bool enable = args[0]->BooleanValue(env->isolate());
#if OPENSSL_VERSION_MAJOR >= 3 #if OPENSSL_VERSION_MAJOR >= 3

View File

@ -85,6 +85,14 @@ testHelper(
'require("crypto").getFips()', 'require("crypto").getFips()',
{ ...process.env, 'OPENSSL_CONF': ' ' }); { ...process.env, 'OPENSSL_CONF': ' ' });
// Toggling fips with setFips should not be allowed from a worker thread
testHelper(
'stderr',
[],
'Calling crypto.setFips() is not supported in workers',
'new worker_threads.Worker(\'require("crypto").setFips(true);\', { eval: true })',
process.env);
// This should succeed for both FIPS and non-FIPS builds in combination with // This should succeed for both FIPS and non-FIPS builds in combination with
// OpenSSL 1.1.1 or OpenSSL 3.0 // OpenSSL 1.1.1 or OpenSSL 3.0
const test_result = testFipsCrypto(); const test_result = testFipsCrypto();