在敏感数据上使用损坏或弱的加密散列算法¶
ID: py/weak-sensitive-data-hashing
Kind: path-problem
Security severity: 7.5
Severity: warning
Precision: high
Tags:
- security
- external/cwe/cwe-327
- external/cwe/cwe-328
- external/cwe/cwe-916
Query suites:
- python-code-scanning.qls
- python-security-extended.qls
- python-security-and-quality.qls
使用损坏或弱的加密哈希函数会使数据容易受到攻击,不应在与安全相关的代码中使用。
强大的加密哈希函数应能抵抗
原像攻击:如果您知道一个哈希值
h(x)
,您不应该能够轻松地找到输入x
。碰撞攻击:如果您知道一个哈希值
h(x)
,您不应该能够轻松地找到一个具有相同哈希值h(x) = h(y)
的不同输入y
。在输入空间有限的情况下,例如密码,哈希函数还需要计算量大才能抵抗暴力攻击。密码还应在散列之前应用唯一的盐,但这不被此查询考虑。
例如,MD5 和 SHA-1 都已知易受碰撞攻击。
由于在非安全上下文中使用弱加密哈希函数是可以的,因此此查询仅在将这些函数用于散列敏感数据(例如密码、证书、用户名)时发出警报。
使用不是散列算法的损坏或弱的加密算法由py/weak-cryptographic-algorithm
查询处理。
建议¶
确保使用强大的现代加密哈希函数
例如,对于密码和其他输入空间有限的数据,使用 Argon2、scrypt、bcrypt 或 PBKDF2。
在其他情况下,使用 SHA-2 或 SHA-3。
示例¶
以下示例显示了两个用于检查证书的哈希值是否与已知值匹配的函数 - 以防止篡改。第一个函数使用 MD5,已知易受碰撞攻击。第二个函数使用 SHA-256,这是一种强大的加密哈希函数。
import hashlib
def certificate_matches_known_hash_bad(certificate, known_hash):
hash = hashlib.md5(certificate).hexdigest() # BAD
return hash == known_hash
def certificate_matches_known_hash_good(certificate, known_hash):
hash = hashlib.sha256(certificate).hexdigest() # GOOD
return hash == known_hash
示例¶
以下示例显示了两个用于散列密码的函数。第一个函数使用 SHA-256 来散列密码。虽然 SHA-256 是一种强大的加密哈希函数,但它不适合密码散列,因为它不计算量大。
import hashlib
def get_password_hash(password: str, salt: str):
return hashlib.sha256(password + salt).hexdigest() # BAD
第二个函数使用 Argon2(通过 argon2-cffi
PyPI 包),它是一种强大的密码散列算法(默认情况下包括每个密码的盐)。
from argon2 import PasswordHasher
def get_initial_hash(password: str):
ph = PasswordHasher()
return ph.hash(password) # GOOD
def check_password(password: str, known_hash):
ph = PasswordHasher()
return ph.verify(known_hash, password) # GOOD