From bc073eb46031593c53693b0dd041bf3738d7cae7 Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Fri, 13 May 2022 14:46:54 +0100 Subject: [PATCH] python: update py/weak-cryptographic-algorithm to flag use of ECB block mode --- .../Security/CWE-327/BrokenCryptoAlgorithm.ql | 17 +++++++++++------ .../BrokenCryptoAlgorithm.expected | 2 ++ .../test_cryptodome.py | 7 ++++++- .../test_cryptography.py | 11 ++++++++++- 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/python/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.ql b/python/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.ql index 9ee3e49a0a1..9b741c3d76b 100644 --- a/python/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.ql +++ b/python/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.ql @@ -13,13 +13,18 @@ import python import semmle.python.Concepts -from Cryptography::CryptographicOperation operation, Cryptography::CryptographicAlgorithm algorithm +from + Cryptography::CryptographicOperation operation, Cryptography::CryptographicAlgorithm algorithm, + string msgPrefix where algorithm = operation.getAlgorithm() and - algorithm.isWeak() and // `Cryptography::HashingAlgorithm` and `Cryptography::PasswordHashingAlgorithm` are // handled by `py/weak-sensitive-data-hashing` - algorithm instanceof Cryptography::EncryptionAlgorithm -select operation, - "The cryptographic algorithm " + algorithm.getName() + - " is broken or weak, and should not be used." + algorithm instanceof Cryptography::EncryptionAlgorithm and + ( + algorithm.isWeak() and + msgPrefix = "The cryptographic algorithm " + operation.getAlgorithm().getName() + ) + or + operation.getBlockMode().isWeak() and msgPrefix = "The block mode " + operation.getBlockMode() +select operation, msgPrefix + " is broken or weak, and should not be used." diff --git a/python/ql/test/query-tests/Security/CWE-327-BrokenCryptoAlgorithm/BrokenCryptoAlgorithm.expected b/python/ql/test/query-tests/Security/CWE-327-BrokenCryptoAlgorithm/BrokenCryptoAlgorithm.expected index acae4cbfb06..4d6ee66ed47 100644 --- a/python/ql/test/query-tests/Security/CWE-327-BrokenCryptoAlgorithm/BrokenCryptoAlgorithm.expected +++ b/python/ql/test/query-tests/Security/CWE-327-BrokenCryptoAlgorithm/BrokenCryptoAlgorithm.expected @@ -1,2 +1,4 @@ | test_cryptodome.py:11:13:11:42 | ControlFlowNode for Attribute() | The cryptographic algorithm ARC4 is broken or weak, and should not be used. | +| test_cryptodome.py:16:13:16:42 | ControlFlowNode for Attribute() | The block mode ECB is broken or weak, and should not be used. | | test_cryptography.py:13:13:13:44 | ControlFlowNode for Attribute() | The cryptographic algorithm ARC4 is broken or weak, and should not be used. | +| test_cryptography.py:22:13:22:58 | ControlFlowNode for Attribute() | The block mode ECB is broken or weak, and should not be used. | diff --git a/python/ql/test/query-tests/Security/CWE-327-BrokenCryptoAlgorithm/test_cryptodome.py b/python/ql/test/query-tests/Security/CWE-327-BrokenCryptoAlgorithm/test_cryptodome.py index 7e5fe780d61..16482054eb2 100644 --- a/python/ql/test/query-tests/Security/CWE-327-BrokenCryptoAlgorithm/test_cryptodome.py +++ b/python/ql/test/query-tests/Security/CWE-327-BrokenCryptoAlgorithm/test_cryptodome.py @@ -1,5 +1,5 @@ # snippet from python/ql/test/experimental/library-tests/frameworks/cryptodome/test_rc4.py -from Cryptodome.Cipher import ARC4 +from Cryptodome.Cipher import ARC4, AES import os @@ -11,3 +11,8 @@ cipher = ARC4.new(key) encrypted = cipher.encrypt(secret_message) # NOT OK print(secret_message, encrypted) + +cipher = AES.new(key, AES.MODE_ECB) +encrypted = cipher.encrypt(secret_message) # NOT OK + +print(secret_message, encrypted) diff --git a/python/ql/test/query-tests/Security/CWE-327-BrokenCryptoAlgorithm/test_cryptography.py b/python/ql/test/query-tests/Security/CWE-327-BrokenCryptoAlgorithm/test_cryptography.py index 2698f9c30d1..4c7317cdba4 100644 --- a/python/ql/test/query-tests/Security/CWE-327-BrokenCryptoAlgorithm/test_cryptography.py +++ b/python/ql/test/query-tests/Security/CWE-327-BrokenCryptoAlgorithm/test_cryptography.py @@ -1,5 +1,5 @@ # snippet from python/ql/test/experimental/library-tests/frameworks/cryptography/test_rc4.py -from cryptography.hazmat.primitives.ciphers import algorithms, Cipher +from cryptography.hazmat.primitives.ciphers import algorithms, modes, Cipher import os key = os.urandom(256//8) @@ -14,3 +14,12 @@ encrypted = encryptor.update(secret_message) # NOT OK encrypted += encryptor.finalize() print(secret_message, encrypted) + +algorithm = algorithms.AES(key) +cipher = Cipher(algorithm, mode=modes.ECB()) + +encryptor = cipher.encryptor() +encrypted = encryptor.update(secret_message + b'\x80\x00') # NOT OK +encrypted += encryptor.finalize() + +print(secret_message, encrypted)