Skip to content

Swift: detect the use of constant salts #10993

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 7, 2022

Conversation

karimhamdanali
Copy link
Contributor

Constant salts should not be used for password hashing. Data hashed using constant salts are vulnerable to dictionary attacks, enabling attackers to recover the original input.

The rule currently supports all ciphers that the CryptoSwift API provides, but we can always extend it further if more APIs are added.

I'd appreciate a review of the query itself, the accompanying tests, and the associated documentation.

@github-actions
Copy link
Contributor

github-actions bot commented Oct 26, 2022

QHelp previews:

swift/ql/src/queries/Security/CWE-760/ConstantSalt.qhelp

Use of constant salts

Constant salts should not be used for password hashing. Data hashed using constant salts are vulnerable to dictionary attacks, enabling attackers to recover the original input.

Recommendation

Use randomly generated salts to securely hash input data.

Example

The following example shows a few cases of hashing input data. In the 'BAD' cases, the salt is constant, making the generated hashes vulnerable to dictionary attacks. In the 'GOOD' cases, the salt is randomly generated, which protects the hashed data against recovery.


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

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

	// GOOD: Using randomly generated salts for hashing
	let salt = (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: randomArray, salt: salt, info: randomArray, keyLength: 0, variant: Variant.sha2)
	_ = try PKCS5.PBKDF1(password: randomArray, salt: salt, iterations: 120120, keyLength: 0)
	_ = try PKCS5.PBKDF2(password: randomArray, salt: salt, iterations: 120120, keyLength: 0)
	_ = try Scrypt(password: randomArray, salt: salt, dkLen: 64, N: 16384, r: 8, p: 1)

	// ...
}

References

exists(ClassOrStructDecl c, AbstractFunctionDecl f, CallExpr call, int arg |
c.getFullName() = ["HKDF", "PBKDF1", "PBKDF2", "Scrypt"] and
c.getAMember() = f and
f.getName().matches("%init(%salt:%") and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a great start, my only concern is how often salts are specified in the wild using the functions modelled above. I did a quick MRVA query for parameters called "salt" (or similar) and the most common call that appears to be relevant is to a thing called CCKeyDerivationPBKDF(_:_:_:_:_:_:_:_:_:) from CommonCrypto. Do you think we should perhaps create a follow-up issue to add a model of that to this query as well?

Copy link
Contributor Author

@karimhamdanali karimhamdanali Oct 31, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add further support for CommonCrytpo, not just for this query, but perhaps other crypto queries too. This might be a good first step in supporting more crypto APIs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind creating an issue for that, listing the support you think we need to add?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Just added one with an initial set of tasks along with some useful resources.

geoffw0
geoffw0 previously approved these changes Oct 31, 2022
Copy link
Contributor

@geoffw0 geoffw0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possible future expansions aside, I'm happy with this query. Ready for docs review?

@karimhamdanali karimhamdanali added the ready-for-doc-review This PR requires and is ready for review from the GitHub docs team. label Nov 1, 2022
@lucascosti
Copy link

👋 Docs first responder here! I've put this on our review board for a writer to review

@karimhamdanali
Copy link
Contributor Author

Thanks @lucascosti for adding this PR to your review board. I was wondering though if a team member will be able to pick it up this week for docs review?

@mchammer01
Copy link
Contributor

@karimhamdanali 👋🏻 - I've picked this up for editorial review and will review this for you today 😃

@mchammer01 mchammer01 self-requested a review November 7, 2022 09:49
mchammer01
mchammer01 previously approved these changes Nov 7, 2022
Copy link
Contributor

@mchammer01 mchammer01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@karimhamdanali 👋🏻 - this LGTM ✨
Left a few comments for your consideration.

@karimhamdanali karimhamdanali dismissed stale reviews from mchammer01 and geoffw0 via 1756fea November 7, 2022 11:20
Copy link
Contributor

@mchammer01 mchammer01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM :shipit:

@karimhamdanali karimhamdanali merged commit 5766ff2 into github:main Nov 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation ready-for-doc-review This PR requires and is ready for review from the GitHub docs team. Swift
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants