Weak Encryption Mode of Operation

ID

csharp.weak_encryption_mode_of_operation

Severity

critical

Remediation Complexity

medium

Remediation Risk

medium

Remediation Effort

medium

Resource

Cryptography

Language

CSharp

Tags

ASVS50:v11.2.1, ASVS50:v11.6.1, CWE:327, NIST.SP.800-53, OWASP:2025:A04, PCI-DSS:6.5.3, crypto

Description

A symmetric cipher is configured to use a broken or risky mode of operation. In the .NET cryptography API the mode is selected through the System.Security.Cryptography.CipherMode enumeration, and setting it to CipherMode.ECB (Electronic Codebook) selects a mode that must not be used to protect confidential data.

The unsafe mode can reach the cipher through a property assignment, an object initializer, or an argument to CreateEncryptor / CreateDecryptor.

var aes = Aes.Create();
aes.Mode = CipherMode.ECB;   // VULNERABLE: identical plaintext blocks produce identical ciphertext

var des = new DESCryptoServiceProvider
{
    Mode = CipherMode.ECB    // VULNERABLE
};

Rationale

The Electronic Codebook (ECB) mode encrypts each block of plaintext independently, so identical plaintext blocks always produce identical ciphertext blocks. This leaks structure and patterns of the plaintext (the classic example is that an encrypted bitmap still reveals its image), which defeats the confidentiality that encryption is meant to provide. ECB also offers no integrity protection, so an attacker can reorder, duplicate, or splice ciphertext blocks undetected.

Because the weakness is in the mode of operation, it applies regardless of how strong the underlying algorithm or key is: AES in ECB mode is still insecure.

Remediation

Use an authenticated mode of operation such as GCM (AesGcm), which provides both confidentiality and integrity. If an authenticated mode is not available, use CBC with a random, unpredictable IV per message and apply a separate integrity check (encrypt-then-MAC).

// Preferred: authenticated encryption (confidentiality + integrity)
using var aesGcm = new AesGcm(key);
aesGcm.Encrypt(nonce, plaintext, ciphertext, tag);

// Acceptable: CBC with a fresh random IV per message, plus a separate MAC
var aes = Aes.Create();
aes.Mode = CipherMode.CBC;   // FIXED: no longer ECB
aes.GenerateIV();            // random IV per message

Never select CipherMode.ECB, and do not disable the mode of operation as a workaround.