Use of a Risky Cryptographic Cipher Mode in cryptography
Module
Using weak cipher modes, such as Electronic Codebook (ECB), for cryptographic algorithms is generally discouraged due to significant security vulnerabilities associated with them.
ECB mode is highly vulnerable to various attacks, primarily because it encrypts each block of plaintext independently. As a result, identical plaintext blocks will produce identical ciphertext blocks. This can leak information about the underlying data, and patterns within the data may be discernible, making it easier for attackers to exploit these patterns.
ECB mode also does not provide diffusion, which means that changes in the plaintext have a limited impact on the ciphertext. This lack of diffusion makes it easier for attackers to manipulate or infer information from the ciphertext.
Because of the determinism in ECB mode, it is susceptible to chosen-plaintext attacks, where an attacker can manipulate the input data to reveal patterns or vulnerabilities in the encryption.
ECB mode is designed for block ciphers, which means it can only encrypt data in fixed-size blocks. If you need to encrypt larger messages, you would have to implement additional techniques (e.g., chaining modes) which can be complex and prone to implementation errors.
Example
import os
from cryptography.hazmat.primitives.ciphers import Cipher
from cryptography.hazmat.primitives.ciphers import algorithms
from cryptography.hazmat.primitives.ciphers import modes
key = os.urandom(32)
algorithm = algorithms.AES(key)
mode = modes.ECB()
cipher = Cipher(algorithm, mode=mode)
encryptor = cipher.encryptor()
ct = encryptor.update(b"a secret message") + encryptor.finalize()
Remediation
It is advisable to use a secure cryptographic algorithms such as CBC.
import os
from cryptography.hazmat.primitives.ciphers import Cipher
from cryptography.hazmat.primitives.ciphers import algorithms
from cryptography.hazmat.primitives.ciphers import modes
key = os.urandom(32)
iv = os.urandom(16)
algorithm = algorithms.AES(key)
mode = modes.CBC(iv)
cipher = Cipher(algorithm, mode=mode)
encryptor = cipher.encryptor()
ct = encryptor.update(b"a secret message") + encryptor.finalize()
False Positives
In the case of a false positive the rule can be suppressed. Simply add a
trailing or preceding comment line with either the rule ID (PY503
) or
rule category name (reversible_one_way_hash
).
- Using rule ID
- Using category name
import os
from cryptography.hazmat.primitives.ciphers import Cipher
from cryptography.hazmat.primitives.ciphers import algorithms
from cryptography.hazmat.primitives.ciphers import modes
key = os.urandom(32)
algorithm = algorithms.AES(key)
# suppress: PY503
mode = modes.ECB()
cipher = Cipher(algorithm, mode=mode)
encryptor = cipher.encryptor()
ct = encryptor.update(b"a secret message") + encryptor.finalize()
import os
from cryptography.hazmat.primitives.ciphers import Cipher
from cryptography.hazmat.primitives.ciphers import algorithms
from cryptography.hazmat.primitives.ciphers import modes
key = os.urandom(32)
algorithm = algorithms.AES(key)
# suppress: use_of_risky_cryptographic_cipher_mode
mode = modes.ECB()
cipher = Cipher(algorithm, mode=mode)
encryptor = cipher.encryptor()
ct = encryptor.update(b"a secret message") + encryptor.finalize()