Skip to content

VNX-325: Missing Cryptographic Step

Reports AES in an unauthenticated mode (CBC, CTR, CFB, OFB) in Java, Kotlin, Node.js, PHP, Python and Ruby, in a file that never computes a MAC or signature, so the integrity step is missing. AEAD modes, ECB (VNX-CRYPTO-003) and files with an HMAC are not reported.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-325
Severity Medium
SARIF level warning
Kind sast
Languages Java, Kotlin, JavaScript / TypeScript, PHP, Python, Ruby
CWE CWE-325
CAPEC CAPEC-66
ATT&CK T1190
CWSS vector CWSS:1.0/TI:M/AP:A/AL:A/IC:N/FC:LT/RP:N/RL:A/AV:I/AS:N/IN:A/SC:A/BI:M/DI:H/EX:M/EC:N/P:C
Tags missing-crypto-step cwe-325 crypto unauthenticated-encryption
Source internal/sast/rules/vnx-325.rego

Overview

VNX-325 maps to CWE-325: Missing Cryptographic Step. It reports AES set up in a mode that provides confidentiality only (CBC, CTR, CFB, OFB, PCBC) when the same file never computes a MAC, an AEAD tag or a signature.

Why This Matters

Encryption without authentication lets an attacker flip bits in the ciphertext and have the change decrypt silently. CBC decryption without a MAC is also a padding oracle: an error that distinguishes bad padding is enough to decrypt the whole message.

What Gets Flagged

// FLAGGED: no Mac anywhere in the file
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
# FLAGGED
cipher = AES.new(key, AES.MODE_CBC, iv)
enc = Cipher(algorithms.AES(key), modes.CTR(iv)).encryptor()
// FLAGGED
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
$ct = openssl_encrypt($plain, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);   // no hash_hmac in the file
cipher = OpenSSL::Cipher.new("aes-256-cbc")

What Is Not Flagged

  • AEAD modes: GCM, CCM, EAX, SIV, OCB, ChaCha20-Poly1305.
  • A file that also computes an HMAC, CMAC, Poly1305 tag or signature (Mac.getInstance, hmac.new, createHmac, Signature).
  • ECB and bare "AES", which VNX-CRYPTO-003 reports.
  • Comments, Python string literals and test files.

A MAC computed in a different file is not seen, so check a finding against its caller.

Remediation

  1. Prefer an AEAD: AES-GCM or ChaCha20-Poly1305.
  2. Otherwise encrypt-then-MAC: HMAC-SHA256 over the IV and ciphertext with a separate key, verified in constant time before decrypting.

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-325
// nosec vnx-325

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

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