no-insecure-rsa-padding
ESLint rule documentation for no-insecure-rsa-padding
📡 Live from GitHub — This documentation is fetched directly from no-insecure-rsa-padding.md and cached for 6 hours.
Keywords: RSA, PKCS#1, padding, Marvin Attack, CVE-2023-46809, OAEP, CWE-327, security, ESLint rule CWE: CWE-327
CVE: CVE-2023-46809
OWASP: A02:2021-Cryptographic Failures
Disallow RSA PKCS#1 v1.5 padding (CVE-2023-46809 Marvin Attack)
Detects usage of RSA PKCS#1 v1.5 padding which is vulnerable to the Marvin Attack. This rule is part of eslint-plugin-node-security and provides LLM-optimized error messages with fix suggestions.
🚨 Security rule | 💡 Provides suggestions | ⚠️ Set to error in recommended
Quick Summary
| Aspect | Details |
|---|---|
| CWE Reference | CWE-327 (Broken Crypto) |
| CVE Reference | CVE-2023-46809 |
| Severity | High (security vulnerability) |
| Auto-Fix | 💡 Suggests OAEP padding |
| Category | Security |
| ESLint MCP | ✅ Optimized for ESLint MCP integration |
| Best For | Node.js applications using RSA encryption |
Vulnerability and Risk
Vulnerability: RSA PKCS#1 v1.5 padding is vulnerable to timing side-channel attacks known as the "Marvin Attack" (CVE-2023-46809). Node.js's privateDecrypt() function had a timing vulnerability that allowed attackers to decrypt ciphertexts or forge signatures.
Risk: An attacker who can measure the time taken to decrypt ciphertexts can use statistical analysis to recover the plaintext without knowing the private key. This attack was demonstrated against Node.js in 2023.
Rule Details
This rule detects usage of RSA_PKCS1_PADDING in crypto.privateDecrypt(), crypto.publicDecrypt(), crypto.privateEncrypt(), and crypto.publicEncrypt() calls.
Why This Matters
| Risk | Impact | Solution |
|---|---|---|
| ⏱️ Timing Attack | Measure decryption time to decrypt data | Use RSA_PKCS1_OAEP_PADDING |
| 📜 Signature Forgery | Create valid signatures without key | Never use PKCS#1 v1.5 for encryption |
| 🔒 CVE-2023-46809 | Specific Node.js vulnerability | Update Node.js and use OAEP |
Configuration
| Option | Type | Default | Description |
|---|---|---|---|
allowInTests | boolean | false | Allow in test files |
{
rules: {
'node-security/no-insecure-rsa-padding': ['error', {
allowInTests: false
}]
}
}Examples
❌ Incorrect
import crypto from 'crypto';
// PKCS#1 v1.5 padding - vulnerable to Marvin Attack
const decrypted = crypto.privateDecrypt(
{
key: privateKey,
padding: crypto.constants.RSA_PKCS1_PADDING, // ❌ Vulnerable
},
encryptedData,
);
// Also vulnerable patterns
crypto.publicEncrypt(
{
key: publicKey,
padding: constants.RSA_PKCS1_PADDING, // ❌ Vulnerable
},
data,
);✅ Correct
import crypto from 'crypto';
// Use OAEP padding - secure against padding oracle attacks
const decrypted = crypto.privateDecrypt(
{
key: privateKey,
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING, // ✅ Secure
oaepHash: 'sha256', // Specify hash for OAEP
},
encryptedData,
);
// For encryption
const encrypted = crypto.publicEncrypt(
{
key: publicKey,
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
oaepHash: 'sha256',
},
data,
);
// For signatures, use RSA-PSS instead of PKCS#1 v1.5
const sign = crypto.createSign('RSA-SHA256');
sign.update(data);
const signature = sign.sign({
key: privateKey,
padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
});The Marvin Attack
The Marvin Attack (named after the paranoid android from Hitchhiker's Guide) exploits timing differences in RSA decryption:
- Padding Check Timing: PKCS#1 v1.5 decryption checks if padding is valid
- Error Timing: Different error paths take different times
- Statistical Analysis: Attackers measure thousands of decryption attempts
- Key Recovery: Timing differences reveal the plaintext
Security Impact
| Vulnerability | CWE | OWASP | CVSS | Impact |
|---|---|---|---|---|
| Broken Crypto | 327 | A02:2021 | 7.5 High | Plaintext recovery |
| Timing Attack | 208 | A02:2021 | 5.9 Medium | Side-channel information leak |
Migration Guide
Phase 1: Discovery
{
rules: {
'node-security/no-insecure-rsa-padding': 'warn'
}
}Phase 2: Replacement
// Replace PKCS#1 v1.5 with OAEP
padding: crypto.constants.RSA_PKCS1_PADDING; // ❌ Before
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING; // ✅ AfterPhase 3: Enforcement
{
rules: {
'node-security/no-insecure-rsa-padding': 'error'
}
}Related Rules
no-weak-cipher-algorithm- Detect weak encryption algorithmsno-insecure-key-derivation- Detect weak key derivation
Known False Negatives
Variable Padding Constants
Why: Dynamic values cannot be analyzed statically.
// ❌ NOT DETECTED
const padding = getPaddingFromConfig();
crypto.privateDecrypt({ key, padding }, data);Mitigation: Use constants directly, avoid indirection.
Further Reading
- Marvin Attack Paper - Original research
- CVE-2023-46809 - Node.js vulnerability
- CWE-327: Broken Crypto Algorithm - Official CWE entry
- OAEP Explained - Wikipedia