Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions swift/ql/lib/change-notes/2023-05-30-sensitive-exprs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Added new heuristics to `SensitiveExprs.qll`, enhancing detection from the library.
55 changes: 38 additions & 17 deletions swift/ql/lib/codeql/swift/security/SensitiveExprs.qll
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class SensitiveCredential extends SensitiveDataType, TCredential {
result = HeuristicNames::maybeSensitiveRegexp(classification)
)
or
result = "(?is).*(account|accnt|license).?(id|key).*"
result = "(?is).*((account|accnt|licen(se|ce)).?(id|key)|one.?time.?code|pass.?phrase).*"
}
}

Expand All @@ -50,21 +50,26 @@ class SensitivePrivateInfo extends SensitiveDataType, TPrivateInfo {
"(?is).*(" +
// Inspired by the list on https://cwe.mitre.org/data/definitions/359.html
// Government identifiers, such as Social Security Numbers
"social.?security|national.?insurance|" +
"social.?security|employer.?identification|national.?insurance|resident.?id|" +
"passport.?(num|no)|" +
// Contact information, such as home addresses
"post.?code|zip.?code|home.?address|" +
"post.?code|zip.?code|home.?addr|" +
// and telephone numbers
"(mob(ile)?|home).?(num|no|tel|phone)|(tel|fax).?(num|no)|telephone|" +
"(mob(ile)?|home).?(num|no|tel|phone)|(tel|fax).?(num|no|phone)|" + "emergency.?contact|" +
// Geographic location - where the user is (or was)
"latitude|longitude|" +
"l(atitude|ongitude)|nationality|" +
// Financial data - such as credit card numbers, salary, bank accounts, and debts
"credit.?card|debit.?card|salary|bank.?account|acc(ou)?nt.?(no|num)|" +
"(credit|debit|bank|visa).?(card|num|no|acc(ou?)nt)|acc(ou)?nt.?(no|num|credit)|" +
"salary|billing|credit.?(rating|score)|" +
// Communications - e-mail addresses, private e-mail messages, SMS text messages, chat logs, etc.
"email|" +
"e(mail|_mail)|" +
// Health - medical conditions, insurance status, prescription records
"birthday|birth.?date|date.?of.?birth|medical|" +
"birth.?da(te|y)|da(te|y).?(of.?)?birth|" +
"medical|(health|care).?plan|healthkit|appointment|prescription|" +
"blood.?(type|alcohol|glucose|pressure)|heart.?(rate|rhythm)|body.?(mass|fat)|" +
"menstrua|pregnan|insulin|inhaler|" +
// Relationships - work and family
"employer|spouse" +
"employ(er|ee)|spouse|maiden.?name" +
// ---
").*"
}
Expand All @@ -80,13 +85,32 @@ private string regexpProbablySafe() {
result = "(?is).*(file|path|url|invalid).*"
}

/**
* Gets a string that is to be tested for sensitivity.
*/
private string sensitiveCandidateStrings() {
result = any(VarDecl v).getName()
or
result = any(Function f).getShortName()
or
result = any(Argument a).getLabel()
}

/**
* Gets a string from the candidates that is sensitive.
*/
private string sensitiveStrings(SensitiveDataType sensitiveType) {
result = sensitiveCandidateStrings() and
result.regexpMatch(sensitiveType.getRegexp())
}

/**
* A `VarDecl` that might be used to contain sensitive data.
*/
private class SensitiveVarDecl extends VarDecl {
SensitiveDataType sensitiveType;

SensitiveVarDecl() { this.getName().regexpMatch(sensitiveType.getRegexp()) }
SensitiveVarDecl() { this.getName() = sensitiveStrings(sensitiveType) }

predicate hasInfo(string label, SensitiveDataType type) {
label = this.getName() and
Expand All @@ -99,15 +123,11 @@ private class SensitiveVarDecl extends VarDecl {
*/
private class SensitiveFunction extends Function {
SensitiveDataType sensitiveType;
string name; // name of the function, not including the argument list.

SensitiveFunction() {
name = this.getShortName() and
name.regexpMatch(sensitiveType.getRegexp())
}
SensitiveFunction() { this.getShortName() = sensitiveStrings(sensitiveType) }

predicate hasInfo(string label, SensitiveDataType type) {
label = name and
label = this.getShortName() and
sensitiveType = type
}
}
Expand All @@ -118,7 +138,7 @@ private class SensitiveFunction extends Function {
private class SensitiveArgument extends Argument {
SensitiveDataType sensitiveType;

SensitiveArgument() { this.getLabel().regexpMatch(sensitiveType.getRegexp()) }
SensitiveArgument() { this.getLabel() = sensitiveStrings(sensitiveType) }

predicate hasInfo(string label, SensitiveDataType type) {
label = this.getLabel() and
Expand Down Expand Up @@ -169,6 +189,7 @@ class SensitiveExpr extends Expr {
* A function that is likely used to encrypt or hash data.
*/
private class EncryptionFunction extends Function {
cached
EncryptionFunction() { this.getName().regexpMatch("(?is).*(crypt|hash|encode|protect).*") }
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@ edges
| testSend.swift:33:14:33:32 | call to Data.init(_:) | testSend.swift:37:19:37:19 | data2 |
| testSend.swift:33:19:33:19 | passwordPlain | testSend.swift:33:14:33:32 | call to Data.init(_:) |
| testSend.swift:41:10:41:18 | data | testSend.swift:41:45:41:45 | data |
| testSend.swift:52:13:52:13 | password | testSend.swift:59:27:59:27 | str1 |
| testSend.swift:53:13:53:13 | password | testSend.swift:60:27:60:27 | str2 |
| testSend.swift:54:13:54:25 | call to pad(_:) | testSend.swift:61:27:61:27 | str3 |
| testSend.swift:54:17:54:17 | password | testSend.swift:41:10:41:18 | data |
| testSend.swift:54:17:54:17 | password | testSend.swift:54:13:54:25 | call to pad(_:) |
| testURL.swift:13:54:13:54 | passwd | testURL.swift:13:22:13:54 | ... .+(_:_:) ... |
| testURL.swift:15:55:15:55 | account_no | testURL.swift:15:22:15:55 | ... .+(_:_:) ... |
| testURL.swift:16:55:16:55 | credit_card_no | testURL.swift:16:22:16:55 | ... .+(_:_:) ... |
| testSend.swift:58:13:58:13 | password | testSend.swift:65:27:65:27 | str1 |
| testSend.swift:59:13:59:13 | password | testSend.swift:66:27:66:27 | str2 |
| testSend.swift:60:13:60:25 | call to pad(_:) | testSend.swift:67:27:67:27 | str3 |
| testSend.swift:60:17:60:17 | password | testSend.swift:41:10:41:18 | data |
| testSend.swift:60:17:60:17 | password | testSend.swift:60:13:60:25 | call to pad(_:) |
| testURL.swift:17:54:17:54 | passwd | testURL.swift:17:22:17:54 | ... .+(_:_:) ... |
| testURL.swift:19:55:19:55 | account_no | testURL.swift:19:22:19:55 | ... .+(_:_:) ... |
| testURL.swift:20:55:20:55 | credit_card_no | testURL.swift:20:22:20:55 | ... .+(_:_:) ... |
| testURL.swift:28:55:28:55 | e_mail | testURL.swift:28:22:28:55 | ... .+(_:_:) ... |
| testURL.swift:30:57:30:57 | a_homeaddr_z | testURL.swift:30:22:30:57 | ... .+(_:_:) ... |
| testURL.swift:32:55:32:55 | resident_ID | testURL.swift:32:22:32:55 | ... .+(_:_:) ... |
nodes
| testAlamofire.swift:150:13:150:45 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... |
| testAlamofire.swift:150:45:150:45 | password | semmle.label | password |
Expand All @@ -26,36 +29,55 @@ nodes
| testSend.swift:37:19:37:19 | data2 | semmle.label | data2 |
| testSend.swift:41:10:41:18 | data | semmle.label | data |
| testSend.swift:41:45:41:45 | data | semmle.label | data |
| testSend.swift:52:13:52:13 | password | semmle.label | password |
| testSend.swift:53:13:53:13 | password | semmle.label | password |
| testSend.swift:54:13:54:25 | call to pad(_:) | semmle.label | call to pad(_:) |
| testSend.swift:54:17:54:17 | password | semmle.label | password |
| testSend.swift:59:27:59:27 | str1 | semmle.label | str1 |
| testSend.swift:60:27:60:27 | str2 | semmle.label | str2 |
| testSend.swift:61:27:61:27 | str3 | semmle.label | str3 |
| testSend.swift:65:27:65:27 | license_key | semmle.label | license_key |
| testSend.swift:66:27:66:30 | .mobileNumber | semmle.label | .mobileNumber |
| testURL.swift:13:22:13:54 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... |
| testURL.swift:13:54:13:54 | passwd | semmle.label | passwd |
| testURL.swift:15:22:15:55 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... |
| testURL.swift:15:55:15:55 | account_no | semmle.label | account_no |
| testURL.swift:16:22:16:55 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... |
| testURL.swift:16:55:16:55 | credit_card_no | semmle.label | credit_card_no |
| testURL.swift:20:22:20:22 | passwd | semmle.label | passwd |
| testSend.swift:58:13:58:13 | password | semmle.label | password |
| testSend.swift:59:13:59:13 | password | semmle.label | password |
| testSend.swift:60:13:60:25 | call to pad(_:) | semmle.label | call to pad(_:) |
| testSend.swift:60:17:60:17 | password | semmle.label | password |
| testSend.swift:65:27:65:27 | str1 | semmle.label | str1 |
| testSend.swift:66:27:66:27 | str2 | semmle.label | str2 |
| testSend.swift:67:27:67:27 | str3 | semmle.label | str3 |
| testSend.swift:71:27:71:27 | license_key | semmle.label | license_key |
| testSend.swift:72:27:72:30 | .mobileNumber | semmle.label | .mobileNumber |
| testSend.swift:76:27:76:30 | .Telephone | semmle.label | .Telephone |
| testSend.swift:77:27:77:30 | .birth_day | semmle.label | .birth_day |
| testSend.swift:78:27:78:30 | .CarePlanID | semmle.label | .CarePlanID |
| testSend.swift:79:27:79:30 | .BankCardNo | semmle.label | .BankCardNo |
| testSend.swift:80:27:80:30 | .MyCreditRating | semmle.label | .MyCreditRating |
| testURL.swift:17:22:17:54 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... |
| testURL.swift:17:54:17:54 | passwd | semmle.label | passwd |
| testURL.swift:19:22:19:55 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... |
| testURL.swift:19:55:19:55 | account_no | semmle.label | account_no |
| testURL.swift:20:22:20:55 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... |
| testURL.swift:20:55:20:55 | credit_card_no | semmle.label | credit_card_no |
| testURL.swift:24:22:24:22 | passwd | semmle.label | passwd |
| testURL.swift:28:22:28:55 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... |
| testURL.swift:28:55:28:55 | e_mail | semmle.label | e_mail |
| testURL.swift:30:22:30:57 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... |
| testURL.swift:30:57:30:57 | a_homeaddr_z | semmle.label | a_homeaddr_z |
| testURL.swift:32:22:32:55 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... |
| testURL.swift:32:55:32:55 | resident_ID | semmle.label | resident_ID |
subpaths
| testSend.swift:54:17:54:17 | password | testSend.swift:41:10:41:18 | data | testSend.swift:41:45:41:45 | data | testSend.swift:54:13:54:25 | call to pad(_:) |
| testSend.swift:60:17:60:17 | password | testSend.swift:41:10:41:18 | data | testSend.swift:41:45:41:45 | data | testSend.swift:60:13:60:25 | call to pad(_:) |
#select
| testAlamofire.swift:150:13:150:45 | ... .+(_:_:) ... | testAlamofire.swift:150:45:150:45 | password | testAlamofire.swift:150:13:150:45 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testAlamofire.swift:150:45:150:45 | password | password |
| testAlamofire.swift:152:19:152:51 | ... .+(_:_:) ... | testAlamofire.swift:152:51:152:51 | password | testAlamofire.swift:152:19:152:51 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testAlamofire.swift:152:51:152:51 | password | password |
| testAlamofire.swift:154:14:154:46 | ... .+(_:_:) ... | testAlamofire.swift:154:38:154:38 | email | testAlamofire.swift:154:14:154:46 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testAlamofire.swift:154:38:154:38 | email | email |
| testSend.swift:29:19:29:19 | passwordPlain | testSend.swift:29:19:29:19 | passwordPlain | testSend.swift:29:19:29:19 | passwordPlain | This operation transmits 'passwordPlain', which may contain unencrypted sensitive data from $@. | testSend.swift:29:19:29:19 | passwordPlain | passwordPlain |
| testSend.swift:37:19:37:19 | data2 | testSend.swift:33:19:33:19 | passwordPlain | testSend.swift:37:19:37:19 | data2 | This operation transmits 'data2', which may contain unencrypted sensitive data from $@. | testSend.swift:33:19:33:19 | passwordPlain | passwordPlain |
| testSend.swift:59:27:59:27 | str1 | testSend.swift:52:13:52:13 | password | testSend.swift:59:27:59:27 | str1 | This operation transmits 'str1', which may contain unencrypted sensitive data from $@. | testSend.swift:52:13:52:13 | password | password |
| testSend.swift:60:27:60:27 | str2 | testSend.swift:53:13:53:13 | password | testSend.swift:60:27:60:27 | str2 | This operation transmits 'str2', which may contain unencrypted sensitive data from $@. | testSend.swift:53:13:53:13 | password | password |
| testSend.swift:61:27:61:27 | str3 | testSend.swift:54:17:54:17 | password | testSend.swift:61:27:61:27 | str3 | This operation transmits 'str3', which may contain unencrypted sensitive data from $@. | testSend.swift:54:17:54:17 | password | password |
| testSend.swift:65:27:65:27 | license_key | testSend.swift:65:27:65:27 | license_key | testSend.swift:65:27:65:27 | license_key | This operation transmits 'license_key', which may contain unencrypted sensitive data from $@. | testSend.swift:65:27:65:27 | license_key | license_key |
| testSend.swift:66:27:66:30 | .mobileNumber | testSend.swift:66:27:66:30 | .mobileNumber | testSend.swift:66:27:66:30 | .mobileNumber | This operation transmits '.mobileNumber', which may contain unencrypted sensitive data from $@. | testSend.swift:66:27:66:30 | .mobileNumber | .mobileNumber |
| testURL.swift:13:22:13:54 | ... .+(_:_:) ... | testURL.swift:13:54:13:54 | passwd | testURL.swift:13:22:13:54 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testURL.swift:13:54:13:54 | passwd | passwd |
| testURL.swift:15:22:15:55 | ... .+(_:_:) ... | testURL.swift:15:55:15:55 | account_no | testURL.swift:15:22:15:55 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testURL.swift:15:55:15:55 | account_no | account_no |
| testURL.swift:16:22:16:55 | ... .+(_:_:) ... | testURL.swift:16:55:16:55 | credit_card_no | testURL.swift:16:22:16:55 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testURL.swift:16:55:16:55 | credit_card_no | credit_card_no |
| testURL.swift:20:22:20:22 | passwd | testURL.swift:20:22:20:22 | passwd | testURL.swift:20:22:20:22 | passwd | This operation transmits 'passwd', which may contain unencrypted sensitive data from $@. | testURL.swift:20:22:20:22 | passwd | passwd |
| testSend.swift:65:27:65:27 | str1 | testSend.swift:58:13:58:13 | password | testSend.swift:65:27:65:27 | str1 | This operation transmits 'str1', which may contain unencrypted sensitive data from $@. | testSend.swift:58:13:58:13 | password | password |
| testSend.swift:66:27:66:27 | str2 | testSend.swift:59:13:59:13 | password | testSend.swift:66:27:66:27 | str2 | This operation transmits 'str2', which may contain unencrypted sensitive data from $@. | testSend.swift:59:13:59:13 | password | password |
| testSend.swift:67:27:67:27 | str3 | testSend.swift:60:17:60:17 | password | testSend.swift:67:27:67:27 | str3 | This operation transmits 'str3', which may contain unencrypted sensitive data from $@. | testSend.swift:60:17:60:17 | password | password |
| testSend.swift:71:27:71:27 | license_key | testSend.swift:71:27:71:27 | license_key | testSend.swift:71:27:71:27 | license_key | This operation transmits 'license_key', which may contain unencrypted sensitive data from $@. | testSend.swift:71:27:71:27 | license_key | license_key |
| testSend.swift:72:27:72:30 | .mobileNumber | testSend.swift:72:27:72:30 | .mobileNumber | testSend.swift:72:27:72:30 | .mobileNumber | This operation transmits '.mobileNumber', which may contain unencrypted sensitive data from $@. | testSend.swift:72:27:72:30 | .mobileNumber | .mobileNumber |
| testSend.swift:76:27:76:30 | .Telephone | testSend.swift:76:27:76:30 | .Telephone | testSend.swift:76:27:76:30 | .Telephone | This operation transmits '.Telephone', which may contain unencrypted sensitive data from $@. | testSend.swift:76:27:76:30 | .Telephone | .Telephone |
| testSend.swift:77:27:77:30 | .birth_day | testSend.swift:77:27:77:30 | .birth_day | testSend.swift:77:27:77:30 | .birth_day | This operation transmits '.birth_day', which may contain unencrypted sensitive data from $@. | testSend.swift:77:27:77:30 | .birth_day | .birth_day |
| testSend.swift:78:27:78:30 | .CarePlanID | testSend.swift:78:27:78:30 | .CarePlanID | testSend.swift:78:27:78:30 | .CarePlanID | This operation transmits '.CarePlanID', which may contain unencrypted sensitive data from $@. | testSend.swift:78:27:78:30 | .CarePlanID | .CarePlanID |
| testSend.swift:79:27:79:30 | .BankCardNo | testSend.swift:79:27:79:30 | .BankCardNo | testSend.swift:79:27:79:30 | .BankCardNo | This operation transmits '.BankCardNo', which may contain unencrypted sensitive data from $@. | testSend.swift:79:27:79:30 | .BankCardNo | .BankCardNo |
| testSend.swift:80:27:80:30 | .MyCreditRating | testSend.swift:80:27:80:30 | .MyCreditRating | testSend.swift:80:27:80:30 | .MyCreditRating | This operation transmits '.MyCreditRating', which may contain unencrypted sensitive data from $@. | testSend.swift:80:27:80:30 | .MyCreditRating | .MyCreditRating |
| testURL.swift:17:22:17:54 | ... .+(_:_:) ... | testURL.swift:17:54:17:54 | passwd | testURL.swift:17:22:17:54 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testURL.swift:17:54:17:54 | passwd | passwd |
| testURL.swift:19:22:19:55 | ... .+(_:_:) ... | testURL.swift:19:55:19:55 | account_no | testURL.swift:19:22:19:55 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testURL.swift:19:55:19:55 | account_no | account_no |
| testURL.swift:20:22:20:55 | ... .+(_:_:) ... | testURL.swift:20:55:20:55 | credit_card_no | testURL.swift:20:22:20:55 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testURL.swift:20:55:20:55 | credit_card_no | credit_card_no |
| testURL.swift:24:22:24:22 | passwd | testURL.swift:24:22:24:22 | passwd | testURL.swift:24:22:24:22 | passwd | This operation transmits 'passwd', which may contain unencrypted sensitive data from $@. | testURL.swift:24:22:24:22 | passwd | passwd |
| testURL.swift:28:22:28:55 | ... .+(_:_:) ... | testURL.swift:28:55:28:55 | e_mail | testURL.swift:28:22:28:55 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testURL.swift:28:55:28:55 | e_mail | e_mail |
| testURL.swift:30:22:30:57 | ... .+(_:_:) ... | testURL.swift:30:57:30:57 | a_homeaddr_z | testURL.swift:30:22:30:57 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testURL.swift:30:57:30:57 | a_homeaddr_z | a_homeaddr_z |
| testURL.swift:32:22:32:55 | ... .+(_:_:) ... | testURL.swift:32:55:32:55 | resident_ID | testURL.swift:32:22:32:55 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testURL.swift:32:55:32:55 | resident_ID | resident_ID |
Loading