Skip to content

Swift: Improve documentation and examples that use encryption#17126

Merged
geoffw0 merged 6 commits into
github:mainfrom
geoffw0:swiftcleartext
Aug 2, 2024
Merged

Swift: Improve documentation and examples that use encryption#17126
geoffw0 merged 6 commits into
github:mainfrom
geoffw0:swiftcleartext

Conversation

@geoffw0
Copy link
Copy Markdown
Contributor

@geoffw0 geoffw0 commented Aug 1, 2024

Swift: Improve query documentation and examples that involve encryption:

  • replace pseudocode in examples with more realistic code (for the swift/cleartext-* queries).
  • mention key management in the .qhelps, and provide a reference to help with that.
  • use the correct initializer for CryptoSwift's CBC class in examples and tests.

@geoffw0 geoffw0 added documentation no-change-note-required This PR does not need a change note ready-for-doc-review This PR requires and is ready for review from the GitHub docs team. Swift labels Aug 1, 2024
@geoffw0 geoffw0 requested a review from a team as a code owner August 1, 2024 16:03
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Aug 1, 2024

QHelp previews:

swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.qhelp

Cleartext storage of sensitive information in a local database

Sensitive information that is stored unencrypted in a database is accessible to an attacker who gains access to that database. For example, the information could be accessed by any process or user in a rooted device, or exposed through another vulnerability.

Recommendation

Either encrypt the entire database, or ensure that each piece of sensitive information is encrypted before being stored. In general, decrypt sensitive information only at the point where it is necessary for it to be used in cleartext. Avoid storing sensitive information at all if you do not need to keep it.

Example

The following example shows three cases of storing information using the Core Data library. In the 'BAD' case, the data that is stored is sensitive (a credit card number) and is not encrypted. In the 'GOOD' cases, the data is either not sensitive, or is protected with encryption. When encryption is used, take care to select a secure modern encryption algorithm, and put suitable key management practices into place.

import CryptoKit

private func encrypt(_ text: String, _ encryptionKey: SymmetricKey) -> String {
	let sealedBox = try! AES.GCM.seal(Data(text.utf8), using: encryptionKey)
	return sealedBox.combined!.base64EncodedString()
}

func storeMyData(databaseObject : NSManagedObject, faveSong : String, creditCardNo : String, encryptionKey: SymmetricKey) {
	// ...

	// GOOD: not sensitive information
	databaseObject.setValue(faveSong, forKey: "myFaveSong")

	// BAD: sensitive information saved in cleartext
	databaseObject.setValue(creditCardNo, forKey: "myCreditCardNo")

	// GOOD: encrypted sensitive information saved
	databaseObject.setValue(encrypt(creditCardNo, encryptionKey), forKey: "myCreditCardNo")

	// ...
}

References

swift/ql/src/queries/Security/CWE-311/CleartextTransmission.qhelp

Cleartext transmission of sensitive information

Sensitive information that is transmitted without encryption may be accessible to an attacker.

Recommendation

Ensure that sensitive information is always encrypted before being transmitted over the network. In general, decrypt sensitive information only at the point where it is necessary for it to be used in cleartext. Avoid transmitting sensitive information when it is not necessary to.

Example

The following example shows three cases of transmitting information. In the 'BAD' case, the data transmitted is sensitive (a credit card number) and is not encrypted. In the 'GOOD' cases, the data is either not sensitive, or is protected with encryption. When encryption is used, take care to select a secure modern encryption algorithm, and put suitable key management practices into place.

import CryptoKit

private func encrypt(_ text: String, _ encryptionKey: SymmetricKey) -> String {
	let sealedBox = try! AES.GCM.seal(Data(text.utf8), using: encryptionKey)
	return sealedBox.combined!.base64EncodedString()
}

func transmitMyData(connection : NWConnection, faveSong : String, creditCardNo : String, encryptionKey: SymmetricKey) {
	// ...

	// GOOD: not sensitive information
	connection.send(content: faveSong, completion: .idempotent)

	// BAD: sensitive information saved in cleartext
	connection.send(content: creditCardNo, completion: .idempotent)

	// GOOD: encrypted sensitive information saved
	connection.send(content: encrypt(creditCardNo, encryptionKey), completion: .idempotent)

	// ...
}

References

swift/ql/src/queries/Security/CWE-312/CleartextStoragePreferences.qhelp

Cleartext storage of sensitive information in an application preference store

Sensitive information that is stored unencrypted in an application preference store, such as the user defaults database or the iCloud-backed ubiquitous key-value store, is accessible to an attacker who gains access to that data store. For example, the information could be accessed by any process or user in a rooted device, by compromised app extensions, or could be exposed through another vulnerability.

Recommendation

Either store the data in an encrypted database, or ensure that each piece of sensitive information is encrypted before being stored. In general, decrypt sensitive information only at the point where it is necessary for it to be used in cleartext. Avoid storing sensitive information at all if you do not need to keep it.

Example

The following example shows three cases of storing information using UserDefaults. In the 'BAD' case, the data that is stored is sensitive (a credit card number) and is not encrypted. In the 'GOOD' cases, the data is either not sensitive, or is protected with encryption. When encryption is used, take care to select a secure modern encryption algorithm, and put suitable key management practices into place.

import CryptoKit

private func encrypt(_ text: String, _ encryptionKey: SymmetricKey) -> String {
	let sealedBox = try! AES.GCM.seal(Data(text.utf8), using: encryptionKey)
	return sealedBox.combined!.base64EncodedString()
}

func storeMyData(faveSong : String, creditCardNo : String, encryptionKey: SymmetricKey) {
	// ...

	// GOOD: not sensitive information
	UserDefaults.standard.set(faveSong, forKey: "myFaveSong")

	// BAD: sensitive information saved in cleartext
	UserDefaults.standard.set(creditCardNo, forKey: "myCreditCardNo")

	// GOOD: encrypted sensitive information saved
	UserDefaults.standard.set(encrypt(creditCardNo, encryptionKey), forKey: "myCreditCardNo")

	// ...
}

References

subatoi
subatoi previously approved these changes Aug 1, 2024
Copy link
Copy Markdown
Contributor

@subatoi subatoi left a comment

Choose a reason for hiding this comment

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

Thank you! Just the "one" comment

Comment thread swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.qhelp Outdated
Comment thread swift/ql/src/queries/Security/CWE-311/CleartextTransmission.qhelp Outdated
Comment thread swift/ql/src/queries/Security/CWE-312/CleartextStoragePreferences.qhelp Outdated
Comment thread swift/ql/src/queries/Security/CWE-311/CleartextTransmission.qhelp Outdated
Co-authored-by: Ben Ahmady <32935794+subatoi@users.noreply.github.com>
@geoffw0 geoffw0 merged commit 49335e5 into github:main Aug 2, 2024
@geoffw0 geoffw0 deleted the swiftcleartext branch October 29, 2024 16:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation no-change-note-required This PR does not need a change note 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.

3 participants