VNX-780: Use of RSA Algorithm without OAEP
RSA encryption or decryption with PKCS#1 v1.5 or no padding in Java, Kotlin, Python, Node.js, Go, PHP, Ruby and C#.
| Field | Value |
|---|---|
| Rule ID | VNX-780 |
| Severity | Medium |
| SARIF level | warning |
| Kind | sast |
| Languages | Java, Kotlin, Python, JavaScript / TypeScript, Go, PHP, Ruby, C# |
| CWE | CWE-780 |
| CAPEC | CAPEC-66 |
| ATT&CK | T1190 |
| CWSS vector | CWSS:1.0/TI:M/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:M/DI:H/EX:M/EC:N/P:C |
| Tags | crypto rsa-no-padding cwe-780 |
| Source | internal/sast/rules/vnx-780.rego |
Overview
VNX-780 maps to CWE-780: Use of RSA Algorithm without OAEP. It reports RSA encryption and decryption that use PKCS#1 v1.5 padding or no padding:
- Java/Kotlin
Cipher.getInstance("RSA"),"RSA/ECB/PKCS1Padding","RSA/NONE/NoPadding"(inline, on the next line or through a constant), BouncyCastlenew PKCS1Encoding(...) - Python
padding.PKCS1v15()passed toencrypt()/decrypt(), PyCryptodomeCrypto.Cipher.PKCS1_v1_5.new(), python-rsarsa.encrypt()/rsa.decrypt() - Node.js
publicEncrypt/privateDecryptwithRSA_PKCS1_PADDINGorRSA_NO_PADDING, node-rsaencryptionScheme: 'pkcs1',new JSEncrypt() - Go
rsa.EncryptPKCS1v15,rsa.DecryptPKCS1v15,rsa.DecryptPKCS1v15SessionKey - PHP
openssl_public_encrypt/openssl_private_decryptwith no padding argument or a PKCS1/no-padding constant, phpseclib PKCS1 encryption mode - Ruby
public_encrypt/private_decryptwith no padding argument orPKCS1_PADDING/NO_PADDING - C#
rsa.Encrypt(data, false),RSAEncryptionPadding.Pkcs1
Not reported: OAEP, PKCS#1 v1.5 signatures (sign/verify, SignPKCS1v15, RSASignaturePadding.Pkcs1), Node publicEncrypt with a bare key (its default is OAEP), and transformations passed in as parameters. Java Cipher.getInstance is also covered by VNX-JAVA-018.
Why This Matters
A service that decrypts PKCS#1 v1.5 ciphertext and reveals, through an error or timing, whether the padding was valid is a padding oracle: Bleichenbacher’s attack recovers the plaintext (often a session key) with adaptive queries. Unpadded RSA is deterministic and malleable.
What Gets Flagged
Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding"); // FLAGGED
return public_key.encrypt(message, padding.PKCS1v15()) # FLAGGED
return rsa.EncryptPKCS1v15(rand.Reader, pub, msg) // FLAGGED
Not flagged:
return rsa.EncryptOAEP(sha256.New(), rand.Reader, pub, msg, nil)
Remediation
- Use OAEP with SHA-256:
RSA/ECB/OAEPWithSHA-256AndMGF1Padding,padding.OAEP(...),rsa.EncryptOAEP,RSA_PKCS1_OAEP_PADDING,OPENSSL_PKCS1_OAEP_PADDING,RSAEncryptionPadding.OaepSHA256. - Prefer a hybrid scheme (RSA-OAEP or ECDH to wrap an AES-GCM key) for anything larger than a key.
References
Suppressing this rule
Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):
# nosec vnx-780
// nosec vnx-780
Or record an ignore rule: vulnetix ignore add --rule vnx-780 --reason "...". See Suppressing findings.