CodeQL documentation

Constant password

ID: swift/constant-password
Kind: path-problem
Security severity: 6.8
Severity: error
Precision: high
Tags:
   - security
   - external/cwe/cwe-259
Query suites:
   - swift-code-scanning.qls
   - swift-security-extended.qls
   - swift-security-and-quality.qls

Click to see the query in the CodeQL repository

Deriving password-based encryption keys using hardcoded passwords is insecure, because the generated key may be easily discovered. Data hashed using constant salts is vulnerable to dictionary attacks, enabling attackers to recover the original input.

In particular, constant passwords would enable easier recovery of the key, even in the presence of a salt. If that salt is random enough, then key recovery is not as easy as just looking up a hardcoded credential in the source code.

Recommendation

Use randomly generated passwords to securely derive a password-based encryption key.

Example

The following example shows a few cases of hashing input data. In the ‘BAD’ cases, the password is constant, making the derived key vulnerable to dictionary attakcs. In the ‘GOOD’ cases, the password is randomly generated, which protects the hashed data against recovery.


func encrypt(padding : Padding) {
	// ...

	// BAD: Using constant passwords for hashing
	let password: Array<UInt8> = [0x2a, 0x3a, 0x80, 0x05]
	let randomArray = (0..<10).map({ _ in UInt8.random(in: 0...UInt8.max) })
	_ = try HKDF(password: password, salt: randomArray, info: randomArray, keyLength: 0, variant: Variant.sha2)
	_ = try PKCS5.PBKDF1(password: password, salt: randomArray, iterations: 120120, keyLength: 0)
	_ = try PKCS5.PBKDF2(password: password, salt: randomArray, iterations: 120120, keyLength: 0)
	_ = try Scrypt(password: password, salt: randomArray, dkLen: 64, N: 16384, r: 8, p: 1)

	// GOOD: Using randomly generated passwords for hashing
	let password = (0..<10).map({ _ in UInt8.random(in: 0...UInt8.max) })
	let randomArray = (0..<10).map({ _ in UInt8.random(in: 0...UInt8.max) })
	_ = try HKDF(password: password, salt: randomArray, info: randomArray, keyLength: 0, variant: Variant.sha2)
	_ = try PKCS5.PBKDF1(password: password, salt: randomArray, iterations: 120120, keyLength: 0)
	_ = try PKCS5.PBKDF2(password: password, salt: randomArray, iterations: 120120, keyLength: 0)
	_ = try Scrypt(password: password, salt: randomArray, dkLen: 64, N: 16384, r: 8, p: 1)

	// ...
}

References

  • © GitHub, Inc.
  • Terms
  • Privacy