Skip to content

VNX-CRYPTO-004: Broken or obsolete cipher

Reports construction of DES, Triple DES, RC4, RC2, Blowfish, CAST5 or IDEA ciphers in Python, Node.js, Go, Java, Ruby and PHP (PyCryptodome/cryptography, createCipheriv names, crypto/des and crypto/rc4, Cipher.getInstance transformations and SecretKeySpec algorithms, OpenSSL::Cipher, openssl_encrypt and mcrypt). TLS cipher-suite deny-lists, names in lists or comparisons, block-size constants, lookalike names, comments, strings and test files are not reported.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-CRYPTO-004
Severity High
SARIF level error
Kind sast
Languages Python, JavaScript / TypeScript, Go, Java, Ruby, PHP
CWE CWE-327
CAPEC CAPEC-97
ATT&CK T1557
CWSS vector CWSS:1.0/TI:H/AP:A/AL:A/IC:N/FC:LT/RP:N/RL:A/AV:I/AS:N/IN:A/SC:A/BI:H/DI:H/EX:H/EC:N/P:H
Tags weak-crypto des rc4 blowfish cipher
Source internal/sast/rules/vnx-crypto-004.rego

Overview

This rule detects usage of symmetric ciphers that are known to be cryptographically broken or officially deprecated: DES (56-bit key, exhaustively brute-forced in 1998), Triple-DES/3DES (Sweet32 birthday attack), RC4 (statistical biases, BEAST/CRIME variants), and Blowfish (64-bit block size, Sweet32 vulnerability). All of these algorithms have been replaced by AES, and their continued use creates exploitable weaknesses in data confidentiality. This maps to CWE-327 (Use of a Broken or Risky Cryptographic Algorithm).

Why This Matters

DES has an effective key length of 56 bits, which was broken by the EFF’s “Deep Crack” hardware in under 23 hours in 1998. Any modern attacker with cloud access can brute-force DES-encrypted data in minutes.

3DES (Triple DES) was designed as a stopgap with an effective security of 112 bits, which was acceptable until the 2016 Sweet32 attack: because 3DES uses a 64-bit block size, roughly 32 GB of data encrypted under the same key creates a birthday collision that leaks plaintext XOR values. NIST deprecated 3DES in 2017 and disallowed it after 2023.

RC4 is a stream cipher with well-documented statistical biases. The first few bytes of the keystream are predictable, and the RC4-based BEAST and CRIME TLS attacks demonstrated plaintext recovery of session cookies in real-world web browsers. TLS 1.3 removed RC4 entirely.

Blowfish, like 3DES, uses a 64-bit block size and is vulnerable to Sweet32. It was a reasonable choice in the 1990s but has no place in new code.

What Gets Flagged

The rule matches cipher names and API calls across all supported languages:

# FLAGGED: PyCryptodome DES
from Crypto.Cipher import DES
cipher = DES.new(key, DES.MODE_CBC)
// FLAGGED: Java 3DES cipher
Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");

// FLAGGED: Java RC4
Cipher rc4 = Cipher.getInstance("RC4");

// FLAGGED: a DES key, and a weak cipher behind a configuration default
SecretKeySpec spec = new SecretKeySpec(raw, "DES");
String alg = props.getProperty("crypto.alg", "DESede/ECB/PKCS5Padding");
Cipher c = Cipher.getInstance(alg);

Java is reported by this rule alone. VNX-928 reads the same JCA and Bouncy Castle forms for Kotlin only, so a weak cipher in a .java file is one finding, not two.

// FLAGGED: Go DES
import "crypto/des"
block, _ := des.NewCipher(key)

// FLAGGED: Go RC4
import "crypto/rc4"
cipher, _ := rc4.NewCipher(key)
// FLAGGED: Node.js DES-CBC
const cipher = crypto.createCipheriv('des-cbc', key, iv);

Not flagged: AES and ChaCha20, TLS cipher-suite names in a deny-list (TLS_RSA_WITH_3DES_EDE_CBC_SHA in a list of suites to disable), a cipher name in a list or comparison, constants such as des.BlockSize, the import alone, names that merely contain the letters (description, rc4Count), comments, strings, documentation and test files.

Remediation

  1. Replace all usages with AES-256-GCM. AES-GCM is the NIST-recommended default for symmetric authenticated encryption. It is hardware-accelerated, has a 128-bit block size (no Sweet32 risk), and provides both confidentiality and integrity.

    # SAFE: AES-256-GCM with authenticated encryption
    import os
    from Crypto.Cipher import AES
    key = os.urandom(32)   # 256-bit
    nonce = os.urandom(12) # 96-bit nonce
    cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)
    ciphertext, tag = cipher.encrypt_and_digest(plaintext)
    // SAFE: AES-256-GCM in Java
    KeyGenerator keyGen = KeyGenerator.getInstance("AES");
    keyGen.init(256, new SecureRandom());
    SecretKey key = keyGen.generateKey();
    Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
  2. For stream cipher use cases, use ChaCha20-Poly1305. ChaCha20-Poly1305 is an IETF-standardized AEAD cipher (RFC 8439) that performs well on devices without AES hardware acceleration (e.g., older ARM microcontrollers).

    // SAFE: Go ChaCha20-Poly1305
    import "golang.org/x/crypto/chacha20poly1305"
    aead, _ := chacha20poly1305.New(key)
    nonce := make([]byte, aead.NonceSize())
    io.ReadFull(rand.Reader, nonce)
    ciphertext := aead.Seal(nonce, nonce, plaintext, nil)
  3. Remove weak ciphers from TLS configurations. If these cipher names appear in TLS configuration files, remove them and ensure only TLS 1.2+ with AEAD cipher suites (AES-GCM, ChaCha20-Poly1305) are permitted.

  4. Migrate stored data. If you have data encrypted with DES, 3DES, or RC4, plan a migration: decrypt with the old key and re-encrypt with AES-GCM. Prioritize sensitive data (PII, credentials, payment data) first.

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-crypto-004
// nosec vnx-crypto-004

Or record an ignore rule: vulnetix ignore add --rule vnx-crypto-004 --reason "...". See Suppressing findings.

Edit this pageSources: cli/internal/sast/rules/vnx-crypto-004.rego, cli/internal/sast/docs/vnx-crypto-004.md
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.