CVE-2023-46809 - Node.js and the Marvin Attack — Exploiting Weaknesses in PKCS #1 v1.5 Padding with OpenSSL
CVE-2023-46809 reveals a serious security issue for Node.js applications that use unpatched OpenSSL libraries and allow PKCS #1 v1.5 padding in RSA private key decryption. Let’s break down what this means, walk through how the vulnerability works, and show how an attacker might exploit it — including code sniplets and practical advice. We’ll also give you helpful links for the original research.
What is CVE-2023-46809?
Node.js ships with its own build of OpenSSL. If your Node.js version bundles (or dynamically loads) an unpatched OpenSSL, it could be vulnerable to a side-channel attack called “Marvin.” This attack targets the way OpenSSL handles PKCS #1 v1.5 padding when RSA private key decryption is allowed.
- Attack Reference: Marvin Attack (Red Hat Research)
- OpenSSL Security Advisory: OpenSSL 3..8 Release Notes
- Node.js Security Blog: Node.js Security Releases for January 2023
Why does this matter?
PKCS #1 v1.5 is an old standard for padding data in RSA encryption. Despite newer, more secure methods (like OAEP), v1.5 is still used in some places. If using RSA decryption with PKCS #1 v1.5 and an unpatched OpenSSL, attackers can use the Marvin Attack to recover private key bits — breaking encryption.
How Does the Marvin Attack Work?
The Marvin Attack is a “padding oracle” attack. By sending different ciphertexts to a system and timing (or measuring some signal from) its responses, an attacker can gain information about the private key.
This hinges on OpenSSL’s old, inconsistent handling of errors in PKCS #1 v1.5 padding.
- If you give it a badly padded message, the error can be slightly different depending on the underlying operation, which leaks information to the attacker.
Simple Exploit Scenario
1. Attacker finds a service (like a Node.js API) that uses crypto.privateDecrypt() with PKCS #1 v1.5 padding.
Here’s a sample of insecure Node.js code
const crypto = require('crypto');
const fs = require('fs');
const privateKey = fs.readFileSync('private.pem');
const data = Buffer.from('...'); // Attacker sends this
// INSECURE: PKCS1_PADDING is vulnerable if OpenSSL is unpatched!
const decrypted = crypto.privateDecrypt(
{
key: privateKey,
padding: crypto.constants.RSA_PKCS1_PADDING
},
data
);
console.log(decrypted.toString());
If your app does something like this — accepting arbitrary input for decryption with v1.5 padding — it can be targeted.
A Marvin exploit is sophisticated, but in summary
# Pseudocode: how an attacker interacts (simplified)
for attempt in range(100000):
fake_encrypted_block = os.urandom(KEY_SIZE)
response = api_send_to_decrypt(fake_encrypted_block)
analyze(response) # Look for subtle differences (timing, errors)
# Over time, reconstruct the private key
1. Upgrade Node.js
Always run the latest Node.js with patched OpenSSL. Node.js 18.13. and 14.21.3 (or newer) bundle OpenSSL versions that fix Marvin.
- Download latest Node.js
2. Reject PKCS #1 v1.5 Padding
Where possible, change padding: crypto.constants.RSA_PKCS1_OAEP_PADDING (OAEP is secure). If you must support v1.5, apply rate-limiting and never show detailed errors.
3. Check OpenSSL Version
If dynamically linking, make sure your OpenSSL is at least 1.1.1t or 3..8.
openssl version
# Should show 1.1.1t or 3..8+
4. Avoid Arbitrary Decryption
Don’t let users or external inputs trigger privateDecrypt() unless strictly necessary.
Resources and References
- 💻 Original Marvin Attack Research (Red Hat)
- 🛡️ Node.js Jan 2023 Security Advisory
- 📝 OpenSSL Security Advisory Feb 2023
Summary & Final Tips
CVE-2023-46809 is a wake-up call: if you use Node.js and OpenSSL, patch often and review your use of PKCS #1 v1.5 padding. Padding oracle attacks aren’t new, but Marvin made them practical against the real world.
Monitor Node.js security releases.
Stay smart, stay updated — and always be skeptical of legacy cryptography settings.
*This post is exclusive to you — hopefully making the Marvin Attack and CVE-2023-46809 much clearer. Share with your Node.js team or fellow developers to help secure the whole ecosystem!*
Timeline
Published on: 09/07/2024 16:15:02 UTC
Last modified on: 09/09/2024 18:35:01 UTC