mirror of
https://github.com/github/codeql.git
synced 2026-04-25 00:35:20 +02:00
Merge pull request #13190 from geoffw0/sharedsensitive
Swift: Adopt the shared sensitive data library
This commit is contained in:
@@ -511,7 +511,8 @@
|
||||
"SensitiveDataHeuristics Python/JS": [
|
||||
"javascript/ql/lib/semmle/javascript/security/internal/SensitiveDataHeuristics.qll",
|
||||
"python/ql/lib/semmle/python/security/internal/SensitiveDataHeuristics.qll",
|
||||
"ruby/ql/lib/codeql/ruby/security/internal/SensitiveDataHeuristics.qll"
|
||||
"ruby/ql/lib/codeql/ruby/security/internal/SensitiveDataHeuristics.qll",
|
||||
"swift/ql/lib/codeql/swift/security/internal/SensitiveDataHeuristics.qll"
|
||||
],
|
||||
"CFG": [
|
||||
"csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll",
|
||||
@@ -598,4 +599,4 @@
|
||||
"python/ql/lib/semmle/python/security/internal/EncryptionKeySizes.qll",
|
||||
"java/ql/lib/semmle/code/java/security/internal/EncryptionKeySizes.qll"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
4
swift/ql/.generated.list
generated
4
swift/ql/.generated.list
generated
@@ -368,7 +368,7 @@ lib/codeql/swift/elements.qll 3df0060edd2b2030f4e4d7d5518afe0073d798474d9b1d6185
|
||||
lib/codeql/swift/generated/AstNode.qll 02ca56d82801f942ae6265c6079d92ccafdf6b532f6bcebd98a04029ddf696e4 6216fda240e45bd4302fa0cf0f08f5f945418b144659264cdda84622b0420aa2
|
||||
lib/codeql/swift/generated/AvailabilityInfo.qll 1e38e7f52ccbcecd4dd088eae15c482d87911682dabb426332cc0e207fc6bf2f 7c6640530cdbece90d4172e8d6cfd119656860da08bb61ed4ef3a6757723994f
|
||||
lib/codeql/swift/generated/AvailabilitySpec.qll fb1255f91bb5e41ad4e9c675a2efbc50d0fb366ea2de68ab7eebd177b0795309 144e0c2e7d6c62ecee43325f7f26dcf437881edf0b75cc1bc898c6c4b61fdeaf
|
||||
lib/codeql/swift/generated/Callable.qll c1f214f5ea4da567d3cf2ac4915630ae1e19c939d2aa64cdd5ab06e76de059dc c43fd17a89d016a31584de10e4d4988f3ea10dc26d6b59b3151bb3196e9f0689
|
||||
lib/codeql/swift/generated/Callable.qll 5b6d79a4db8d98ea2255f0773d3512ad195e87fe47bab669d6e24668417ab96d 579506e89ad2385739384ab3fecfb1da699d862ee3a9e9a7225b095b0ec279ff
|
||||
lib/codeql/swift/generated/Comment.qll f58b49f6e68c21f87c51e2ff84c8a64b09286d733e86f70d67d3a98fe6260bd6 975bbb599a2a7adc35179f6ae06d9cbc56ea8a03b972ef2ee87604834bc6deb1
|
||||
lib/codeql/swift/generated/DbFile.qll a49b2a2cb2788cb49c861ebcd458b8daead7b15adb19c3a9f4db3bf39a0051fc a49b2a2cb2788cb49c861ebcd458b8daead7b15adb19c3a9f4db3bf39a0051fc
|
||||
lib/codeql/swift/generated/DbLocation.qll b9baea963d9fa82068986512c0649d1050897654eee3df51dba17cf6b1170873 b9baea963d9fa82068986512c0649d1050897654eee3df51dba17cf6b1170873
|
||||
@@ -383,7 +383,7 @@ lib/codeql/swift/generated/OtherAvailabilitySpec.qll 0e26a203b26ff0581b7396b0c6d
|
||||
lib/codeql/swift/generated/ParentChild.qll 5c5ff9812efbed0adf465d1c8b9108c893c77ff946f6feaaec7223ad38664079 94038dcd8a5e98b959ce9f09b7b54b745b0df49b91339b9396017a209abe8bb7
|
||||
lib/codeql/swift/generated/PlatformVersionAvailabilitySpec.qll f82d9ca416fe8bd59b5531b65b1c74c9f317b3297a6101544a11339a1cffce38 7f5c6d3309e66c134107afe55bae76dfc9a72cb7cdd6d4c3706b6b34cee09fa0
|
||||
lib/codeql/swift/generated/PureSynthConstructors.qll 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98
|
||||
lib/codeql/swift/generated/Raw.qll 87402f6b1a0173503a545b57b06c0e320459410834c9adc7a25b2ae53874075e 49e27ddf824decdf21c0531b1ebb3fa007a869ec63bde9f60d08a68fae12acc6
|
||||
lib/codeql/swift/generated/Raw.qll 991f95f30bde82ba43237bd9c1a68d3f450038ef828edb89219fbf583dd1956a e3e6c41caac09d532453c28167622fae7057d846f35750873eacd48cd128b957
|
||||
lib/codeql/swift/generated/Synth.qll 551fdf7e4b53f9ee1314d1bb42c2638cf82f45bfa1f40a635dfa7b6072e4418c 9ab178464700a19951fc5285acacda4913addee81515d8e072b3d7055935a814
|
||||
lib/codeql/swift/generated/SynthConstructors.qll 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4
|
||||
lib/codeql/swift/generated/UnknownFile.qll 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6
|
||||
|
||||
4
swift/ql/lib/change-notes/2023-05-30-shared-sensitive.md
Normal file
4
swift/ql/lib/change-notes/2023-05-30-shared-sensitive.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: majorAnalysis
|
||||
---
|
||||
* Incorporated the cross-language `SensitiveDataHeuristics.qll` heuristics library into the Swift `SensitiveExprs.qll` library. This adds a number of new heuristics enhancing detection from the library.
|
||||
@@ -6,6 +6,16 @@ private import codeql.swift.elements.decl.Method
|
||||
*/
|
||||
class Function extends Generated::Function, Callable {
|
||||
override string toString() { result = this.getName() }
|
||||
|
||||
/**
|
||||
* Gets the name of this function, without the argument list. For example
|
||||
* a function with name `myFunction(arg:)` has short name `myFunction`.
|
||||
*/
|
||||
string getShortName() {
|
||||
// match as many characters as possible that are not `(`.
|
||||
// (`*+` is possessive matching)
|
||||
result = this.getName().regexpCapture("([^(]*+).*", 1)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
2
swift/ql/lib/codeql/swift/generated/Callable.qll
generated
2
swift/ql/lib/codeql/swift/generated/Callable.qll
generated
@@ -10,6 +10,8 @@ module Generated {
|
||||
class Callable extends Synth::TCallable, Element {
|
||||
/**
|
||||
* Gets the name of this callable, if it exists.
|
||||
*
|
||||
* The name includes argument labels of the callable, for example `myFunction(arg:)`.
|
||||
*/
|
||||
string getName() { result = Synth::convertCallableToRaw(this).(Raw::Callable).getName() }
|
||||
|
||||
|
||||
2
swift/ql/lib/codeql/swift/generated/Raw.qll
generated
2
swift/ql/lib/codeql/swift/generated/Raw.qll
generated
@@ -21,6 +21,8 @@ module Raw {
|
||||
class Callable extends @callable, Element {
|
||||
/**
|
||||
* Gets the name of this callable, if it exists.
|
||||
*
|
||||
* The name includes argument labels of the callable, for example `myFunction(arg:)`.
|
||||
*/
|
||||
string getName() { callable_names(this, result) }
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
import swift
|
||||
import internal.SensitiveDataHeuristics
|
||||
|
||||
private newtype TSensitiveDataType =
|
||||
TCredential() or
|
||||
@@ -29,7 +30,12 @@ class SensitiveCredential extends SensitiveDataType, TCredential {
|
||||
override string toString() { result = "credential" }
|
||||
|
||||
override string getRegexp() {
|
||||
result = ".*(password|passwd|accountid|account.?key|accnt.?key|license.?key|trusted).*"
|
||||
exists(SensitiveDataClassification classification |
|
||||
not classification = SensitiveDataClassification::id() and // not accurate enough
|
||||
result = HeuristicNames::maybeSensitiveRegexp(classification)
|
||||
)
|
||||
or
|
||||
result = "(?is).*(account|accnt|license).?(id|key).*"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +47,7 @@ class SensitivePrivateInfo extends SensitiveDataType, TPrivateInfo {
|
||||
|
||||
override string getRegexp() {
|
||||
result =
|
||||
".*(" +
|
||||
"(?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|" +
|
||||
@@ -52,7 +58,7 @@ class SensitivePrivateInfo extends SensitiveDataType, TPrivateInfo {
|
||||
// Geographic location - where the user is (or was)
|
||||
"latitude|longitude|" +
|
||||
// Financial data - such as credit card numbers, salary, bank accounts, and debts
|
||||
"credit.?card|debit.?card|salary|bank.?account|" +
|
||||
"credit.?card|debit.?card|salary|bank.?account|acc(ou)?nt.?(no|num)|" +
|
||||
// Communications - e-mail addresses, private e-mail messages, SMS text messages, chat logs, etc.
|
||||
"email|" +
|
||||
// Health - medical conditions, insurance status, prescription records
|
||||
@@ -69,7 +75,10 @@ class SensitivePrivateInfo extends SensitiveDataType, TPrivateInfo {
|
||||
* contain hashed or encrypted data, or are only a reference to data that is
|
||||
* actually stored elsewhere.
|
||||
*/
|
||||
private string regexpProbablySafe() { result = ".*(hash|crypt|file|path|url|invalid).*" }
|
||||
private string regexpProbablySafe() {
|
||||
result = HeuristicNames::notSensitiveRegexp() or
|
||||
result = "(?is).*(file|path|url|invalid).*"
|
||||
}
|
||||
|
||||
/**
|
||||
* A `VarDecl` that might be used to contain sensitive data.
|
||||
@@ -77,7 +86,7 @@ private string regexpProbablySafe() { result = ".*(hash|crypt|file|path|url|inva
|
||||
private class SensitiveVarDecl extends VarDecl {
|
||||
SensitiveDataType sensitiveType;
|
||||
|
||||
SensitiveVarDecl() { this.getName().toLowerCase().regexpMatch(sensitiveType.getRegexp()) }
|
||||
SensitiveVarDecl() { this.getName().regexpMatch(sensitiveType.getRegexp()) }
|
||||
|
||||
predicate hasInfo(string label, SensitiveDataType type) {
|
||||
label = this.getName() and
|
||||
@@ -90,11 +99,15 @@ private class SensitiveVarDecl extends VarDecl {
|
||||
*/
|
||||
private class SensitiveFunction extends Function {
|
||||
SensitiveDataType sensitiveType;
|
||||
string name; // name of the function, not including the argument list.
|
||||
|
||||
SensitiveFunction() { this.getName().toLowerCase().regexpMatch(sensitiveType.getRegexp()) }
|
||||
SensitiveFunction() {
|
||||
name = this.getShortName() and
|
||||
name.regexpMatch(sensitiveType.getRegexp())
|
||||
}
|
||||
|
||||
predicate hasInfo(string label, SensitiveDataType type) {
|
||||
label = this.getName() and
|
||||
label = name and
|
||||
sensitiveType = type
|
||||
}
|
||||
}
|
||||
@@ -105,7 +118,7 @@ private class SensitiveFunction extends Function {
|
||||
private class SensitiveArgument extends Argument {
|
||||
SensitiveDataType sensitiveType;
|
||||
|
||||
SensitiveArgument() { this.getLabel().toLowerCase().regexpMatch(sensitiveType.getRegexp()) }
|
||||
SensitiveArgument() { this.getLabel().regexpMatch(sensitiveType.getRegexp()) }
|
||||
|
||||
predicate hasInfo(string label, SensitiveDataType type) {
|
||||
label = this.getLabel() and
|
||||
@@ -138,7 +151,7 @@ class SensitiveExpr extends Expr {
|
||||
)
|
||||
) and
|
||||
// do not mark as sensitive it if it is probably safe
|
||||
not label.toLowerCase().regexpMatch(regexpProbablySafe())
|
||||
not label.regexpMatch(regexpProbablySafe())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,7 +169,7 @@ class SensitiveExpr extends Expr {
|
||||
* A function that is likely used to encrypt or hash data.
|
||||
*/
|
||||
private class EncryptionFunction extends Function {
|
||||
EncryptionFunction() { this.getName().regexpMatch(".*(crypt|hash|encode|protect).*") }
|
||||
EncryptionFunction() { this.getName().regexpMatch("(?is).*(crypt|hash|encode|protect).*") }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*
|
||||
* Provides classes and predicates for identifying strings that may indicate the presence of sensitive data.
|
||||
* Such that we can share this logic across our CodeQL analysis of different languages.
|
||||
*
|
||||
* 'Sensitive' data in general is anything that should not be sent around in unencrypted form.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A classification of different kinds of sensitive data:
|
||||
*
|
||||
* - secret: generic secret or trusted data;
|
||||
* - id: a user name or other account information;
|
||||
* - password: a password or authorization key;
|
||||
* - certificate: a certificate.
|
||||
*
|
||||
* While classifications are represented as strings, this should not be relied upon.
|
||||
* Instead, use the predicates in `SensitiveDataClassification::` to work with
|
||||
* classifications.
|
||||
*/
|
||||
class SensitiveDataClassification extends string {
|
||||
SensitiveDataClassification() { this in ["secret", "id", "password", "certificate"] }
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides predicates to select the different kinds of sensitive data we support.
|
||||
*/
|
||||
module SensitiveDataClassification {
|
||||
/** Gets the classification for secret or trusted data. */
|
||||
SensitiveDataClassification secret() { result = "secret" }
|
||||
|
||||
/** Gets the classification for user names or other account information. */
|
||||
SensitiveDataClassification id() { result = "id" }
|
||||
|
||||
/** Gets the classification for passwords or authorization keys. */
|
||||
SensitiveDataClassification password() { result = "password" }
|
||||
|
||||
/** Gets the classification for certificates. */
|
||||
SensitiveDataClassification certificate() { result = "certificate" }
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*
|
||||
* Provides heuristics for identifying names related to sensitive information.
|
||||
*/
|
||||
module HeuristicNames {
|
||||
/**
|
||||
* Gets a regular expression that identifies strings that may indicate the presence of secret
|
||||
* or trusted data.
|
||||
*/
|
||||
string maybeSecret() { result = "(?is).*((?<!is|is_)secret|(?<!un|un_|is|is_)trusted).*" }
|
||||
|
||||
/**
|
||||
* Gets a regular expression that identifies strings that may indicate the presence of
|
||||
* user names or other account information.
|
||||
*/
|
||||
string maybeAccountInfo() {
|
||||
result = "(?is).*acc(ou)?nt.*" or
|
||||
result = "(?is).*(puid|username|userid|session(id|key)).*" or
|
||||
result = "(?s).*([uU]|^|_|[a-z](?=U))([uU][iI][dD]).*"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a regular expression that identifies strings that may indicate the presence of
|
||||
* a password or an authorization key.
|
||||
*/
|
||||
string maybePassword() {
|
||||
result = "(?is).*pass(wd|word|code|phrase)(?!.*question).*" or
|
||||
result = "(?is).*(auth(entication|ori[sz]ation)?)key.*"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a regular expression that identifies strings that may indicate the presence of
|
||||
* a certificate.
|
||||
*/
|
||||
string maybeCertificate() { result = "(?is).*(cert)(?!.*(format|name)).*" }
|
||||
|
||||
/**
|
||||
* Gets a regular expression that identifies strings that may indicate the presence
|
||||
* of sensitive data, with `classification` describing the kind of sensitive data involved.
|
||||
*/
|
||||
string maybeSensitiveRegexp(SensitiveDataClassification classification) {
|
||||
result = maybeSecret() and classification = SensitiveDataClassification::secret()
|
||||
or
|
||||
result = maybeAccountInfo() and classification = SensitiveDataClassification::id()
|
||||
or
|
||||
result = maybePassword() and classification = SensitiveDataClassification::password()
|
||||
or
|
||||
result = maybeCertificate() and
|
||||
classification = SensitiveDataClassification::certificate()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a regular expression that identifies strings that may indicate the presence of data
|
||||
* that is hashed or encrypted, and hence rendered non-sensitive, or contains special characters
|
||||
* suggesting nouns within the string do not represent the meaning of the whole string (e.g. a URL or a SQL query).
|
||||
*
|
||||
* We also filter out common words like `certain` and `concert`, since otherwise these could
|
||||
* be matched by the certificate regular expressions. Same for `accountable` (account), or
|
||||
* `secretarial` (secret).
|
||||
*/
|
||||
string notSensitiveRegexp() {
|
||||
result =
|
||||
"(?is).*([^\\w$.-]|redact|censor|obfuscate|hash|md5|sha|random|((?<!un)(en))?(crypt|(?<!pass)code)|certain|concert|secretar|accountant|accountab).*"
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `name` may indicate the presence of sensitive data, and
|
||||
* `name` does not indicate that the data is in fact non-sensitive (for example since
|
||||
* it is hashed or encrypted). `classification` describes the kind of sensitive data
|
||||
* involved.
|
||||
*
|
||||
* That is, one of the regexps from `maybeSensitiveRegexp` matches `name` (with the
|
||||
* given classification), and none of the regexps from `notSensitiveRegexp` matches
|
||||
* `name`.
|
||||
*/
|
||||
bindingset[name]
|
||||
predicate nameIndicatesSensitiveData(string name, SensitiveDataClassification classification) {
|
||||
name.regexpMatch(maybeSensitiveRegexp(classification)) and
|
||||
not name.regexpMatch(notSensitiveRegexp())
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ edges
|
||||
| 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 | ... .+(_:_:) ... |
|
||||
nodes
|
||||
| file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) |
|
||||
@@ -40,6 +41,8 @@ nodes
|
||||
| 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 |
|
||||
@@ -58,5 +61,6 @@ subpaths
|
||||
| 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 |
|
||||
|
||||
@@ -53,9 +53,8 @@
|
||||
| testCoreData.swift:58:15:58:15 | password | label:password, type:credential |
|
||||
| testCoreData.swift:61:25:61:25 | password | label:password, type:credential |
|
||||
| testCoreData.swift:64:16:64:16 | password | label:password, type:credential |
|
||||
| testCoreData.swift:77:2:77:25 | call to doSomething(password:) | label:doSomething(password:), type:credential |
|
||||
| testCoreData.swift:77:24:77:24 | x | label:password, type:credential |
|
||||
| testCoreData.swift:80:10:80:22 | call to getPassword() | label:getPassword(), type:credential |
|
||||
| testCoreData.swift:80:10:80:22 | call to getPassword() | label:getPassword, type:credential |
|
||||
| testCoreData.swift:85:15:85:17 | .password | label:password, type:credential |
|
||||
| testCoreData.swift:91:10:91:10 | passwd | label:passwd, type:credential |
|
||||
| testCoreData.swift:92:10:92:10 | passwd | label:passwd, type:credential |
|
||||
@@ -130,5 +129,6 @@
|
||||
| testSend.swift:66:27:66:30 | .mobileNumber | label:mobileNumber, type:private information |
|
||||
| testSend.swift:69:27:69:30 | .passwordFeatureEnabled | label:passwordFeatureEnabled, type:credential |
|
||||
| testURL.swift:13:54:13:54 | passwd | label:passwd, type:credential |
|
||||
| testURL.swift:15:55:15:55 | account_no | label:account_no, type:private information |
|
||||
| testURL.swift:16:55:16:55 | credit_card_no | label:credit_card_no, type:private information |
|
||||
| testURL.swift:20:22:20:22 | passwd | label:passwd, type:credential |
|
||||
|
||||
@@ -12,7 +12,7 @@ struct URL
|
||||
func test1(passwd : String, encrypted_passwd : String, account_no : String, credit_card_no : String) {
|
||||
let a = URL(string: "http://example.com/login?p=" + passwd); // BAD
|
||||
let b = URL(string: "http://example.com/login?p=" + encrypted_passwd); // GOOD (not sensitive)
|
||||
let c = URL(string: "http://example.com/login?ac=" + account_no); // BAD [NOT DETECTED]
|
||||
let c = URL(string: "http://example.com/login?ac=" + account_no); // BAD
|
||||
let d = URL(string: "http://example.com/login?cc=" + credit_card_no); // BAD
|
||||
|
||||
let base = URL(string: "http://example.com/"); // GOOD (not sensitive)
|
||||
|
||||
@@ -1,17 +1,29 @@
|
||||
edges
|
||||
nodes
|
||||
| testCryptoKit.swift:56:47:56:47 | passwd | semmle.label | passwd |
|
||||
| testCryptoKit.swift:57:43:57:43 | cert | semmle.label | cert |
|
||||
| testCryptoKit.swift:59:43:59:43 | account_no | semmle.label | account_no |
|
||||
| testCryptoKit.swift:60:43:60:43 | credit_card_no | semmle.label | credit_card_no |
|
||||
| testCryptoKit.swift:61:43:61:43 | credit_card_no | semmle.label | credit_card_no |
|
||||
| testCryptoKit.swift:63:44:63:44 | passwd | semmle.label | passwd |
|
||||
| testCryptoKit.swift:64:44:64:44 | cert | semmle.label | cert |
|
||||
| testCryptoKit.swift:66:44:66:44 | account_no | semmle.label | account_no |
|
||||
| testCryptoKit.swift:67:44:67:44 | credit_card_no | semmle.label | credit_card_no |
|
||||
| testCryptoKit.swift:90:23:90:23 | passwd | semmle.label | passwd |
|
||||
| testCryptoKit.swift:91:23:91:23 | cert | semmle.label | cert |
|
||||
| testCryptoKit.swift:93:23:93:23 | account_no | semmle.label | account_no |
|
||||
| testCryptoKit.swift:94:23:94:23 | credit_card_no | semmle.label | credit_card_no |
|
||||
| testCryptoKit.swift:99:23:99:23 | passwd | semmle.label | passwd |
|
||||
| testCryptoKit.swift:100:23:100:23 | cert | semmle.label | cert |
|
||||
| testCryptoKit.swift:102:23:102:23 | account_no | semmle.label | account_no |
|
||||
| testCryptoKit.swift:103:23:103:23 | credit_card_no | semmle.label | credit_card_no |
|
||||
| testCryptoKit.swift:132:32:132:32 | passwd | semmle.label | passwd |
|
||||
| testCryptoKit.swift:133:32:133:32 | cert | semmle.label | cert |
|
||||
| testCryptoKit.swift:135:32:135:32 | account_no | semmle.label | account_no |
|
||||
| testCryptoKit.swift:136:32:136:32 | credit_card_no | semmle.label | credit_card_no |
|
||||
| testCryptoKit.swift:141:32:141:32 | passwd | semmle.label | passwd |
|
||||
| testCryptoKit.swift:142:32:142:32 | cert | semmle.label | cert |
|
||||
| testCryptoKit.swift:144:32:144:32 | account_no | semmle.label | account_no |
|
||||
| testCryptoKit.swift:145:32:145:32 | credit_card_no | semmle.label | credit_card_no |
|
||||
| testCryptoSwift.swift:113:30:113:30 | passwdArray | semmle.label | passwdArray |
|
||||
| testCryptoSwift.swift:115:31:115:31 | passwdArray | semmle.label | passwdArray |
|
||||
@@ -26,17 +38,29 @@ nodes
|
||||
subpaths
|
||||
#select
|
||||
| testCryptoKit.swift:56:47:56:47 | passwd | testCryptoKit.swift:56:47:56:47 | passwd | testCryptoKit.swift:56:47:56:47 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:56:47:56:47 | passwd | sensitive data (credential passwd) |
|
||||
| testCryptoKit.swift:57:43:57:43 | cert | testCryptoKit.swift:57:43:57:43 | cert | testCryptoKit.swift:57:43:57:43 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:57:43:57:43 | cert | sensitive data (credential cert) |
|
||||
| testCryptoKit.swift:59:43:59:43 | account_no | testCryptoKit.swift:59:43:59:43 | account_no | testCryptoKit.swift:59:43:59:43 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:59:43:59:43 | account_no | sensitive data (private information account_no) |
|
||||
| testCryptoKit.swift:60:43:60:43 | credit_card_no | testCryptoKit.swift:60:43:60:43 | credit_card_no | testCryptoKit.swift:60:43:60:43 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:60:43:60:43 | credit_card_no | sensitive data (private information credit_card_no) |
|
||||
| testCryptoKit.swift:61:43:61:43 | credit_card_no | testCryptoKit.swift:61:43:61:43 | credit_card_no | testCryptoKit.swift:61:43:61:43 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:61:43:61:43 | credit_card_no | sensitive data (private information credit_card_no) |
|
||||
| testCryptoKit.swift:63:44:63:44 | passwd | testCryptoKit.swift:63:44:63:44 | passwd | testCryptoKit.swift:63:44:63:44 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:63:44:63:44 | passwd | sensitive data (credential passwd) |
|
||||
| testCryptoKit.swift:64:44:64:44 | cert | testCryptoKit.swift:64:44:64:44 | cert | testCryptoKit.swift:64:44:64:44 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:64:44:64:44 | cert | sensitive data (credential cert) |
|
||||
| testCryptoKit.swift:66:44:66:44 | account_no | testCryptoKit.swift:66:44:66:44 | account_no | testCryptoKit.swift:66:44:66:44 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:66:44:66:44 | account_no | sensitive data (private information account_no) |
|
||||
| testCryptoKit.swift:67:44:67:44 | credit_card_no | testCryptoKit.swift:67:44:67:44 | credit_card_no | testCryptoKit.swift:67:44:67:44 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:67:44:67:44 | credit_card_no | sensitive data (private information credit_card_no) |
|
||||
| testCryptoKit.swift:90:23:90:23 | passwd | testCryptoKit.swift:90:23:90:23 | passwd | testCryptoKit.swift:90:23:90:23 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:90:23:90:23 | passwd | sensitive data (credential passwd) |
|
||||
| testCryptoKit.swift:91:23:91:23 | cert | testCryptoKit.swift:91:23:91:23 | cert | testCryptoKit.swift:91:23:91:23 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:91:23:91:23 | cert | sensitive data (credential cert) |
|
||||
| testCryptoKit.swift:93:23:93:23 | account_no | testCryptoKit.swift:93:23:93:23 | account_no | testCryptoKit.swift:93:23:93:23 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:93:23:93:23 | account_no | sensitive data (private information account_no) |
|
||||
| testCryptoKit.swift:94:23:94:23 | credit_card_no | testCryptoKit.swift:94:23:94:23 | credit_card_no | testCryptoKit.swift:94:23:94:23 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:94:23:94:23 | credit_card_no | sensitive data (private information credit_card_no) |
|
||||
| testCryptoKit.swift:99:23:99:23 | passwd | testCryptoKit.swift:99:23:99:23 | passwd | testCryptoKit.swift:99:23:99:23 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:99:23:99:23 | passwd | sensitive data (credential passwd) |
|
||||
| testCryptoKit.swift:100:23:100:23 | cert | testCryptoKit.swift:100:23:100:23 | cert | testCryptoKit.swift:100:23:100:23 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:100:23:100:23 | cert | sensitive data (credential cert) |
|
||||
| testCryptoKit.swift:102:23:102:23 | account_no | testCryptoKit.swift:102:23:102:23 | account_no | testCryptoKit.swift:102:23:102:23 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:102:23:102:23 | account_no | sensitive data (private information account_no) |
|
||||
| testCryptoKit.swift:103:23:103:23 | credit_card_no | testCryptoKit.swift:103:23:103:23 | credit_card_no | testCryptoKit.swift:103:23:103:23 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:103:23:103:23 | credit_card_no | sensitive data (private information credit_card_no) |
|
||||
| testCryptoKit.swift:132:32:132:32 | passwd | testCryptoKit.swift:132:32:132:32 | passwd | testCryptoKit.swift:132:32:132:32 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:132:32:132:32 | passwd | sensitive data (credential passwd) |
|
||||
| testCryptoKit.swift:133:32:133:32 | cert | testCryptoKit.swift:133:32:133:32 | cert | testCryptoKit.swift:133:32:133:32 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:133:32:133:32 | cert | sensitive data (credential cert) |
|
||||
| testCryptoKit.swift:135:32:135:32 | account_no | testCryptoKit.swift:135:32:135:32 | account_no | testCryptoKit.swift:135:32:135:32 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:135:32:135:32 | account_no | sensitive data (private information account_no) |
|
||||
| testCryptoKit.swift:136:32:136:32 | credit_card_no | testCryptoKit.swift:136:32:136:32 | credit_card_no | testCryptoKit.swift:136:32:136:32 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:136:32:136:32 | credit_card_no | sensitive data (private information credit_card_no) |
|
||||
| testCryptoKit.swift:141:32:141:32 | passwd | testCryptoKit.swift:141:32:141:32 | passwd | testCryptoKit.swift:141:32:141:32 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:141:32:141:32 | passwd | sensitive data (credential passwd) |
|
||||
| testCryptoKit.swift:142:32:142:32 | cert | testCryptoKit.swift:142:32:142:32 | cert | testCryptoKit.swift:142:32:142:32 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:142:32:142:32 | cert | sensitive data (credential cert) |
|
||||
| testCryptoKit.swift:144:32:144:32 | account_no | testCryptoKit.swift:144:32:144:32 | account_no | testCryptoKit.swift:144:32:144:32 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:144:32:144:32 | account_no | sensitive data (private information account_no) |
|
||||
| testCryptoKit.swift:145:32:145:32 | credit_card_no | testCryptoKit.swift:145:32:145:32 | credit_card_no | testCryptoKit.swift:145:32:145:32 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:145:32:145:32 | credit_card_no | sensitive data (private information credit_card_no) |
|
||||
| testCryptoSwift.swift:113:30:113:30 | passwdArray | testCryptoSwift.swift:113:30:113:30 | passwdArray | testCryptoSwift.swift:113:30:113:30 | passwdArray | Insecure hashing algorithm (MD5) depends on $@. | testCryptoSwift.swift:113:30:113:30 | passwdArray | sensitive data (credential passwdArray) |
|
||||
| testCryptoSwift.swift:115:31:115:31 | passwdArray | testCryptoSwift.swift:115:31:115:31 | passwdArray | testCryptoSwift.swift:115:31:115:31 | passwdArray | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoSwift.swift:115:31:115:31 | passwdArray | sensitive data (credential passwdArray) |
|
||||
|
||||
@@ -54,16 +54,16 @@ enum Insecure {
|
||||
|
||||
func testHashMethods(passwd : UnsafeRawBufferPointer, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) {
|
||||
var hash = Crypto.Insecure.MD5.hash(data: passwd) // BAD
|
||||
hash = Crypto.Insecure.MD5.hash(data: cert) // BAD [NOT DETECTED]
|
||||
hash = Crypto.Insecure.MD5.hash(data: cert) // BAD
|
||||
hash = Crypto.Insecure.MD5.hash(data: encrypted_passwd) // GOOD (not sensitive)
|
||||
hash = Crypto.Insecure.MD5.hash(data: account_no) // BAD [NOT DETECTED]
|
||||
hash = Crypto.Insecure.MD5.hash(data: account_no) // BAD
|
||||
hash = Crypto.Insecure.MD5.hash(data: credit_card_no) // BAD
|
||||
hash = Crypto.Insecure.MD5.hash(data: credit_card_no) // BAD
|
||||
|
||||
hash = Crypto.Insecure.SHA1.hash(data: passwd) // BAD
|
||||
hash = Crypto.Insecure.SHA1.hash(data: cert) // BAD [NOT DETECTED]
|
||||
hash = Crypto.Insecure.SHA1.hash(data: cert) // BAD
|
||||
hash = Crypto.Insecure.SHA1.hash(data: encrypted_passwd) // GOOD (not sensitive)
|
||||
hash = Crypto.Insecure.SHA1.hash(data: account_no) // BAD [NOT DETECTED]
|
||||
hash = Crypto.Insecure.SHA1.hash(data: account_no) // BAD
|
||||
hash = Crypto.Insecure.SHA1.hash(data: credit_card_no) // BAD
|
||||
|
||||
hash = Crypto.SHA256.hash(data: passwd) // BAD [NOT DETECTED] not a computationally expensive hash
|
||||
@@ -88,18 +88,18 @@ func testHashMethods(passwd : UnsafeRawBufferPointer, cert: String, encrypted_pa
|
||||
func testMD5UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) {
|
||||
var hash = Crypto.Insecure.MD5()
|
||||
hash.update(data: passwd) // BAD
|
||||
hash.update(data: cert) // BAD [NOT DETECTED]
|
||||
hash.update(data: cert) // BAD
|
||||
hash.update(data: encrypted_passwd) // GOOD (not sensitive)
|
||||
hash.update(data: account_no) // BAD [NOT DETECTED]
|
||||
hash.update(data: account_no) // BAD
|
||||
hash.update(data: credit_card_no) // BAD
|
||||
}
|
||||
|
||||
func testSHA1UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) {
|
||||
var hash = Crypto.Insecure.SHA1()
|
||||
hash.update(data: passwd) // BAD
|
||||
hash.update(data: cert) // BAD [NOT DETECTED]
|
||||
hash.update(data: cert) // BAD
|
||||
hash.update(data: encrypted_passwd) // GOOD (not sensitive)
|
||||
hash.update(data: account_no) // BAD [NOT DETECTED]
|
||||
hash.update(data: account_no) // BAD
|
||||
hash.update(data: credit_card_no) // BAD
|
||||
}
|
||||
|
||||
@@ -130,18 +130,18 @@ func testSHA512UpdateWithData(passwd : String, cert: String, encrypted_passwd :
|
||||
func testMD5UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer, cert: UnsafeRawBufferPointer, encrypted_passwd : UnsafeRawBufferPointer, account_no : UnsafeRawBufferPointer, credit_card_no : UnsafeRawBufferPointer) {
|
||||
var hash = Crypto.Insecure.MD5()
|
||||
hash.update(bufferPointer: passwd) // BAD
|
||||
hash.update(bufferPointer: cert) // BAD [NOT DETECTED]
|
||||
hash.update(bufferPointer: cert) // BAD
|
||||
hash.update(bufferPointer: encrypted_passwd) // GOOD (not sensitive)
|
||||
hash.update(bufferPointer: account_no) // BAD [NOT DETECTED]
|
||||
hash.update(bufferPointer: account_no) // BAD
|
||||
hash.update(bufferPointer: credit_card_no) // BAD
|
||||
}
|
||||
|
||||
func testSHA1UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer, cert: UnsafeRawBufferPointer, encrypted_passwd : UnsafeRawBufferPointer, account_no : UnsafeRawBufferPointer, credit_card_no : UnsafeRawBufferPointer) {
|
||||
var hash = Crypto.Insecure.SHA1()
|
||||
hash.update(bufferPointer: passwd) // BAD
|
||||
hash.update(bufferPointer: cert) // BAD [NOT DETECTED]
|
||||
hash.update(bufferPointer: cert) // BAD
|
||||
hash.update(bufferPointer: encrypted_passwd) // GOOD (not sensitive)
|
||||
hash.update(bufferPointer: account_no) // BAD [NOT DETECTED]
|
||||
hash.update(bufferPointer: account_no) // BAD
|
||||
hash.update(bufferPointer: credit_card_no) // BAD
|
||||
}
|
||||
|
||||
|
||||
@@ -235,7 +235,8 @@ class ParamDecl(VarDecl):
|
||||
""")
|
||||
|
||||
class Callable(Element):
|
||||
name: optional[string] | doc("name of this callable")
|
||||
name: optional[string] | doc("name of this callable") | desc("The name includes argument "
|
||||
"labels of the callable, for example `myFunction(arg:)`.")
|
||||
self_param: optional[ParamDecl] | child
|
||||
params: list[ParamDecl] | child
|
||||
body: optional["BraceStmt"] | child | desc("The body is absent within protocol declarations.")
|
||||
|
||||
Reference in New Issue
Block a user