Skip to content

Commit

Permalink
crypto: disable PKCS#1 padding for privateDecrypt
Browse files Browse the repository at this point in the history
Refs: https://hackerone.com/bugs?subject=nodejs&report_id=2269177

Disable RSA_PKCS1_PADDING for crypto.privateDecrypt() in order
to protect against the Marvin attack.

Includes a security revert flag that can be used to restore
support.

Signed-off-by: Michael Dawson <[email protected]>
PR-URL: nodejs-private/node-private#525
Refs: https://hackerone.com/bugs?subject=nodejs&report_id=2269177
Reviewed-By: Rafael Gonzaga <[email protected]>
CVE-ID: CVE-2023-46809
  • Loading branch information
mhdawson authored and marco-ippolito committed Feb 13, 2024
1 parent 6155a1f commit 8344719
Show file tree
Hide file tree
Showing 4 changed files with 535 additions and 14 deletions.
28 changes: 28 additions & 0 deletions src/crypto/crypto_cipher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "node_buffer.h"
#include "node_internals.h"
#include "node_process-inl.h"
#include "node_revert.h"
#include "v8.h"

namespace node {
Expand Down Expand Up @@ -1052,6 +1053,33 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
uint32_t padding;
if (!args[offset + 1]->Uint32Value(env->context()).To(&padding)) return;

if (EVP_PKEY_cipher == EVP_PKEY_decrypt &&
operation == PublicKeyCipher::kPrivate && padding == RSA_PKCS1_PADDING &&
!IsReverted(SECURITY_REVERT_CVE_2023_46809)) {
EVPKeyCtxPointer ctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
CHECK(ctx);

if (EVP_PKEY_decrypt_init(ctx.get()) <= 0) {
return ThrowCryptoError(env, ERR_get_error());
}

int rsa_pkcs1_implicit_rejection =
EVP_PKEY_CTX_ctrl_str(ctx.get(), "rsa_pkcs1_implicit_rejection", "1");
// From the doc -2 means that the option is not supported.
// The default for the option is enabled and if it has been
// specifically disabled we want to respect that so we will
// not throw an error if the option is supported regardless
// of how it is set. The call to set the value
// will not affect what is used since a different context is
// used in the call if the option is supported
if (rsa_pkcs1_implicit_rejection <= 0) {
return THROW_ERR_INVALID_ARG_VALUE(
env,
"RSA_PKCS1_PADDING is no longer supported for private decryption,"
" this can be reverted with --security-revert=CVE-2023-46809");
}
}

const EVP_MD* digest = nullptr;
if (args[offset + 2]->IsString()) {
const Utf8Value oaep_str(env->isolate(), args[offset + 2]);
Expand Down
4 changes: 2 additions & 2 deletions src/node_revert.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
**/
namespace node {

#define SECURITY_REVERSIONS(XX) \
// XX(CVE_2016_PEND, "CVE-2016-PEND", "Vulnerability Title")
#define SECURITY_REVERSIONS(XX) \
XX(CVE_2023_46809, "CVE-2023-46809", "Marvin attack on PKCS#1 padding")

enum reversion {
#define V(code, ...) SECURITY_REVERT_##code,
Expand Down
Loading

0 comments on commit 8344719

Please sign in to comment.