Use of a broken or weak cryptographic hashing algorithm on sensitive data¶
ID: swift/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
Query suites:
- swift-code-scanning.qls
- swift-security-extended.qls
- swift-security-and-quality.qls
Click to see the query in the CodeQL repository
Using a broken or weak cryptographic hash function can leave data vulnerable, and should not be used in security related code.
A strong cryptographic hash function should be resistant to:
Pre-image attacks. If you know a hash value
h(x)
, you should not be able to easily find the inputx
.Collision attacks. If you know a hash value
h(x)
, you should not be able to easily find a different inputy
with the same hash valueh(x) = h(y)
. As an example, both MD5 and SHA-1 are known to be vulnerable to collision attacks.
Since it’s OK to use a weak cryptographic hash function in a non-security context, this query only alerts when these are used to hash sensitive data (such as passwords, certificates, usernames).
Recommendation¶
Ensure that you use a strong, modern cryptographic hash function, such as:
Argon2, scrypt, bcrypt, or PBKDF2 for passwords and other data with limited input space where a dictionary-like attack is feasible.
SHA-2, or SHA-3 in other cases. Note that special purpose algorithms, which are used to ensure that a message comes from a particular sender, exist for message authentication. These algorithms should be used when appropriate, as they address common vulnerabilities of simple hashing schemes in this context.
Example¶
The following examples show a function for fetching data from a URL along with a hash of the data, perhaps to check the data has not been tampered with.
In the first case the MD5 hashing algorithm is used that is known to be vulnerable to collision attacks.
func getContentsAndHash(url: URL) -> (Data, String)? {
guard let data = try? Data(contentsOf: url) else {
return nil
}
let digest = Insecure.MD5.hash(data: data) // BAD: MD5 is not suitable for hashing sensitive data.
let hash = digest.map { String(format: "%02hhx", $0) }.joined()
return (data, hash)
}
Here is the same function using SHA-512, which is a strong cryptographic hashing function.
func getContentsAndHash(url: URL) -> (Data, String)? {
guard let data = try? Data(contentsOf: url) else {
return nil
}
let digest = SHA512.hash(data: data) // GOOD: SHA-512 is suitable for hashing sensitive data.
let hash = digest.map { String(format: "%02hhx", $0) }.joined()
return (data, hash)
}
References¶
OWASP: Password Storage Cheat Sheet and Transport Layer Protection Cheat Sheet
Common Weakness Enumeration: CWE-327.
Common Weakness Enumeration: CWE-328.