mirror of
https://github.com/github/codeql.git
synced 2026-06-12 16:31:10 +02:00
Compare commits
1 Commits
copilot/co
...
copilot/ql
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
49df5bda0d |
@@ -1,2 +1 @@
|
||||
query: queries/Security/CWE-020/IncompleteHostnameRegex.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
queries/Security/CWE-020/IncompleteHostnameRegex.ql
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
query: queries/Security/CWE-020/MissingRegexAnchor.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
queries/Security/CWE-020/MissingRegexAnchor.ql
|
||||
|
||||
@@ -47,63 +47,63 @@ class NSString : NSObject {
|
||||
|
||||
func tests(input: String) throws {
|
||||
_ = try Regex("^a|").firstMatch(in: input)
|
||||
_ = try Regex("^a|b").firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex("^a|b").firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex("a|^b").firstMatch(in: input)
|
||||
_ = try Regex("^a|^b").firstMatch(in: input)
|
||||
_ = try Regex("^a|b|c").firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex("^a|b|c").firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex("a|^b|c").firstMatch(in: input)
|
||||
_ = try Regex("a|b|^c").firstMatch(in: input)
|
||||
_ = try Regex("^a|^b|c").firstMatch(in: input)
|
||||
|
||||
_ = try Regex("(^a)|b").firstMatch(in: input)
|
||||
_ = try Regex("^a|(b)").firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex("^a|(b)").firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex("^a|(^b)").firstMatch(in: input)
|
||||
_ = try Regex("^(a)|(b)").firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex("^(a)|(b)").firstMatch(in: input) // BAD (missing anchor)
|
||||
|
||||
_ = try Regex("a|b$").firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex("a|b$").firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex("a$|b").firstMatch(in: input)
|
||||
_ = try Regex("a$|b$").firstMatch(in: input)
|
||||
_ = try Regex("a|b|c$").firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex("a|b|c$").firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex("a|b$|c").firstMatch(in: input)
|
||||
_ = try Regex("a$|b|c").firstMatch(in: input)
|
||||
_ = try Regex("a|b$|c$").firstMatch(in: input)
|
||||
|
||||
_ = try Regex("a|(b$)").firstMatch(in: input)
|
||||
_ = try Regex("(a)|b$").firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex("(a)|b$").firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex("(a$)|b$").firstMatch(in: input)
|
||||
_ = try Regex("(a)|(b)$").firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex("(a)|(b)$").firstMatch(in: input) // BAD (missing anchor)
|
||||
|
||||
_ = try Regex(#"^good.com|better.com"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"^good\.com|better\.com"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"^good\\.com|better\\.com"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"^good\\\.com|better\\\.com"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"^good\\\\.com|better\\\\.com"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"^good.com|better.com"#).firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex(#"^good\.com|better\.com"#).firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex(#"^good\\.com|better\\.com"#).firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex(#"^good\\\.com|better\\\.com"#).firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex(#"^good\\\\.com|better\\\\.com"#).firstMatch(in: input) // BAD (missing anchor)
|
||||
|
||||
_ = try Regex("^foo|bar|baz$").firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex("^foo|bar|baz$").firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex("^foo|%").firstMatch(in: input)
|
||||
}
|
||||
|
||||
func realWorld(input: String) throws {
|
||||
// real-world examples that have been anonymized a bit
|
||||
// the following are bad:
|
||||
_ = try Regex(#"(\.xxx)|(\.yyy)|(\.zzz)$"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"(^left|right|center)\sbottom$"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"\.xxx|\.yyy|\.zzz$"#).ignoresCase().firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"\.xxx|\.yyy|\.zzz$"#).ignoresCase().firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"\.xxx|\.yyy|zzz$"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"^([A-Z]|xxx[XY]$)"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"^(xxx yyy zzz)|(xxx yyy)"#).ignoresCase().firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"^(xxx yyy zzz)|(xxx yyy)|(1st( xxx)? yyy)|xxx|1st"#).ignoresCase().firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"^(xxx:)|(yyy:)|(zzz:)"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"^(xxx?:)|(yyy:zzz\/)"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"^@media|@page"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"^\s*(xxx?|yyy|zzz):|xxx:yyy"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"^click|mouse|touch"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"^http://good\.com|http://better\.com"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"^https?://good\.com|https?://better\.com"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"^mouse|touch|click|contextmenu|drop|dragover|dragend"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"^xxx:|yyy:"#).ignoresCase().firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"_xxx|_yyy|_zzz$"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"(\.xxx)|(\.yyy)|(\.zzz)$"#).firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex(#"(^left|right|center)\sbottom$"#).firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex(#"\.xxx|\.yyy|\.zzz$"#).ignoresCase().firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex(#"\.xxx|\.yyy|\.zzz$"#).ignoresCase().firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex(#"\.xxx|\.yyy|zzz$"#).firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex(#"^([A-Z]|xxx[XY]$)"#).firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex(#"^(xxx yyy zzz)|(xxx yyy)"#).ignoresCase().firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex(#"^(xxx yyy zzz)|(xxx yyy)|(1st( xxx)? yyy)|xxx|1st"#).ignoresCase().firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex(#"^(xxx:)|(yyy:)|(zzz:)"#).firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex(#"^(xxx?:)|(yyy:zzz\/)"#).firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex(#"^@media|@page"#).firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex(#"^\s*(xxx?|yyy|zzz):|xxx:yyy"#).firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex(#"^click|mouse|touch"#).firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex(#"^http://good\.com|http://better\.com"#).firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex(#"^https?://good\.com|https?://better\.com"#).firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex(#"^mouse|touch|click|contextmenu|drop|dragover|dragend"#).firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex(#"^xxx:|yyy:"#).ignoresCase().firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex(#"_xxx|_yyy|_zzz$"#).firstMatch(in: input) // BAD (missing anchor)
|
||||
_ = try Regex(#"em|%$"#).firstMatch(in: input) // BAD (missing anchor) [NOT DETECTED] - not flagged at the moment due to the anchor not being for letters
|
||||
|
||||
// the following are MAYBE OK due to apparent complexity; not flagged
|
||||
|
||||
@@ -59,36 +59,36 @@ func tests(url: String, secure: Bool) throws {
|
||||
let input = "http://evil.com/?http://good.com"
|
||||
let inputRange = NSMakeRange(0, input.utf16.count)
|
||||
|
||||
_ = try NSRegularExpression(pattern: "https?://good.com").matches(in: input, range: inputRange) // $ Alert // BAD (missing anchor)
|
||||
_ = try NSRegularExpression(pattern: "https?://good.com").matches(in: input, range: inputRange) // $ Alert // BAD (missing anchor)
|
||||
_ = try NSRegularExpression(pattern: "^https?://good.com").matches(in: input, range: inputRange) // $ Alert // BAD (missing post-anchor)
|
||||
_ = try NSRegularExpression(pattern: "(^https?://good1.com)|(^https?://good2.com)").matches(in: input, range: inputRange) // $ Alert // BAD (missing post-anchor)
|
||||
_ = try NSRegularExpression(pattern: "(https?://good.com)|(^https?://goodie.com)").matches(in: input, range: inputRange) // $ Alert // BAD (missing anchor)
|
||||
_ = try NSRegularExpression(pattern: "https?://good.com").matches(in: input, range: inputRange) // BAD (missing anchor)
|
||||
_ = try NSRegularExpression(pattern: "https?://good.com").matches(in: input, range: inputRange) // BAD (missing anchor)
|
||||
_ = try NSRegularExpression(pattern: "^https?://good.com").matches(in: input, range: inputRange) // BAD (missing post-anchor)
|
||||
_ = try NSRegularExpression(pattern: "(^https?://good1.com)|(^https?://good2.com)").matches(in: input, range: inputRange) // BAD (missing post-anchor)
|
||||
_ = try NSRegularExpression(pattern: "(https?://good.com)|(^https?://goodie.com)").matches(in: input, range: inputRange) // BAD (missing anchor)
|
||||
|
||||
_ = try NSRegularExpression(pattern: #"https?:\/\/good.com"#).matches(in: input, range: inputRange) // $ Alert // BAD (missing anchor)
|
||||
_ = try NSRegularExpression(pattern: "https?://good.com").matches(in: input, range: inputRange) // $ Alert // BAD (missing anchor)
|
||||
_ = try NSRegularExpression(pattern: #"https?:\/\/good.com"#).matches(in: input, range: inputRange) // BAD (missing anchor)
|
||||
_ = try NSRegularExpression(pattern: "https?://good.com").matches(in: input, range: inputRange) // BAD (missing anchor)
|
||||
|
||||
if let _ = try NSRegularExpression(pattern: "https?://good.com").firstMatch(in: input, range: inputRange) { } // $ Alert // BAD (missing anchor)
|
||||
if let _ = try NSRegularExpression(pattern: "https?://good.com").firstMatch(in: input, range: inputRange) { } // BAD (missing anchor)
|
||||
|
||||
let input2 = "something"
|
||||
let input2Range = NSMakeRange(0, input2.utf16.count)
|
||||
_ = try NSRegularExpression(pattern: "other").firstMatch(in: input2, range: input2Range) // OK
|
||||
_ = try NSRegularExpression(pattern: "x.commissary").firstMatch(in: input2, range: input2Range) // OK
|
||||
|
||||
_ = try NSRegularExpression(pattern: #"https?://good.com"#).firstMatch(in: input, range: inputRange) // $ Alert // BAD (missing anchor)
|
||||
_ = try NSRegularExpression(pattern: #"https?://good.com:8080"#).firstMatch(in: input, range: inputRange) // $ Alert // BAD (missing anchor)
|
||||
_ = try NSRegularExpression(pattern: #"https?://good.com"#).firstMatch(in: input, range: inputRange) // BAD (missing anchor)
|
||||
_ = try NSRegularExpression(pattern: #"https?://good.com:8080"#).firstMatch(in: input, range: inputRange) // BAD (missing anchor)
|
||||
|
||||
let trustedUrlRegexs = [
|
||||
"https?://good.com", // $ Alert // BAD (missing anchor), referenced below
|
||||
#"https?:\/\/good.com"#, // $ Alert // BAD (missing anchor), referenced below
|
||||
"^https?://good.com" // $ Alert // BAD (missing post-anchor), referenced below
|
||||
"https?://good.com", // BAD (missing anchor), referenced below
|
||||
#"https?:\/\/good.com"#, // BAD (missing anchor), referenced below
|
||||
"^https?://good.com" // BAD (missing post-anchor), referenced below
|
||||
]
|
||||
for trustedUrlRegex in trustedUrlRegexs {
|
||||
if let _ = try NSRegularExpression(pattern: trustedUrlRegex).firstMatch(in: input, range: inputRange) { }
|
||||
}
|
||||
|
||||
let trustedUrlRegexs2 = [
|
||||
"https?://good.com", // $ Alert // BAD (missing anchor), referenced below
|
||||
"https?://good.com", // BAD (missing anchor), referenced below
|
||||
]
|
||||
if let _ = try NSRegularExpression(pattern: trustedUrlRegexs2[0]).firstMatch(in: input, range: inputRange) { }
|
||||
|
||||
@@ -98,13 +98,13 @@ func tests(url: String, secure: Bool) throws {
|
||||
for _ in notUsedUrlRegexs {
|
||||
}
|
||||
|
||||
_ = try NSRegularExpression(pattern: #"https?:\/\/good.com\/([0-9]+)"#).matches(in: url, range: urlRange) // $ Alert // BAD (missing anchor)
|
||||
_ = try NSRegularExpression(pattern: #"https?:\/\/good.com\/([0-9]+)"#).matches(in: url, range: urlRange) // BAD (missing anchor)
|
||||
_ = try NSRegularExpression(pattern: "https://verygood.com/?id=" + #"https?:\/\/good.com\/([0-9]+)"#).matches(in: url, range: urlRange)[0] // OK
|
||||
_ = try NSRegularExpression(pattern: "http" + (secure ? "s" : "") + "://" + "verygood.com/?id=" + #"https?:\/\/good.com\/([0-9]+)"#).matches(in: url, range: urlRange)[0] // OK
|
||||
_ = try NSRegularExpression(pattern: "verygood.com/?id=" + #"https?:\/\/good.com\/([0-9]+)"#).matches(in: url, range: urlRange)[0] // OK
|
||||
|
||||
_ = try NSRegularExpression(pattern: #"\.com|\.org"#).matches(in: input, range: inputRange) // OK, has no domain name
|
||||
_ = try NSRegularExpression(pattern: #"example\.com|whatever"#).matches(in: input, range: inputRange) // $ Alert // OK, the other disjunction doesn't match a hostname [FALSE POSITIVE]
|
||||
_ = try NSRegularExpression(pattern: #"example\.com|whatever"#).matches(in: input, range: inputRange) // OK, the other disjunction doesn't match a hostname [FALSE POSITIVE]
|
||||
|
||||
// tests for the `isLineAnchoredHostnameRegExp` case
|
||||
|
||||
|
||||
@@ -53,49 +53,49 @@ func testHostnames(myUrl: URL) throws {
|
||||
|
||||
_ = try Regex(#"^http://example\.com/"#).firstMatch(in: tainted) // GOOD
|
||||
_ = try Regex(#"^http://example.com/"#).firstMatch(in: tainted) // GOOD (only '.' here gives a valid top-level domain)
|
||||
_ = try Regex(#"^http://example.com"#).firstMatch(in: tainted) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"^http://example.com"#).firstMatch(in: tainted) // BAD (missing anchor)
|
||||
_ = try Regex(#"^http://test\.example\.com/"#).firstMatch(in: tainted) // GOOD
|
||||
_ = try Regex(#"^http://test\.example.com/"#).firstMatch(in: tainted) // GOOD (only '.' here gives a valid top-level domain)
|
||||
_ = try Regex(#"^http://test\.example.com"#).firstMatch(in: tainted) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"^http://test.example.com/"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
|
||||
_ = try Regex(#"^http://test\.example.com"#).firstMatch(in: tainted) // BAD (missing anchor)
|
||||
_ = try Regex(#"^http://test.example.com/"#).firstMatch(in: tainted) // BAD (incomplete hostname)
|
||||
_ = try Regex(#"^http://test[.]example[.]com/"#).firstMatch(in: tainted) // GOOD (alternative method of escaping)
|
||||
|
||||
_ = try Regex(#"^http://test.example.net/"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
|
||||
_ = try Regex(#"^http://test.(example-a|example-b).com/"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
|
||||
_ = try Regex(#"^http://(.+).example.com/"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname x 2)
|
||||
_ = try Regex(#"^http://test.example.net/"#).firstMatch(in: tainted) // BAD (incomplete hostname)
|
||||
_ = try Regex(#"^http://test.(example-a|example-b).com/"#).firstMatch(in: tainted) // BAD (incomplete hostname)
|
||||
_ = try Regex(#"^http://(.+).example.com/"#).firstMatch(in: tainted) // BAD (incomplete hostname x 2)
|
||||
_ = try Regex(#"^http://(\.+)\.example.com/"#).firstMatch(in: tainted) // GOOD
|
||||
_ = try Regex(#"^http://(?:.+)\.test\.example.com/"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
|
||||
_ = try Regex(#"^http://test.example.com/(?:.*)"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
|
||||
_ = try Regex(#"^(.+\.(?:example-a|example-b)\.com)/"#).firstMatch(in: tainted) // $ Alert // BAD (missing anchor)
|
||||
_ = try Regex(#"^(https?:)?//((service|www).)?example.com(?=$|/)"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
|
||||
_ = try Regex(#"^(http|https)://www.example.com/p/f/"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
|
||||
_ = try Regex(#"^(http://sub.example.com/)"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
|
||||
_ = try Regex(#"^https?://api.example.com/"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
|
||||
_ = try Regex(#"^http://(?:.+)\.test\.example.com/"#).firstMatch(in: tainted) // BAD (incomplete hostname)
|
||||
_ = try Regex(#"^http://test.example.com/(?:.*)"#).firstMatch(in: tainted) // BAD (incomplete hostname)
|
||||
_ = try Regex(#"^(.+\.(?:example-a|example-b)\.com)/"#).firstMatch(in: tainted) // BAD (missing anchor)
|
||||
_ = try Regex(#"^(https?:)?//((service|www).)?example.com(?=$|/)"#).firstMatch(in: tainted) // BAD (incomplete hostname)
|
||||
_ = try Regex(#"^(http|https)://www.example.com/p/f/"#).firstMatch(in: tainted) // BAD (incomplete hostname)
|
||||
_ = try Regex(#"^(http://sub.example.com/)"#).firstMatch(in: tainted) // BAD (incomplete hostname)
|
||||
_ = try Regex(#"^https?://api.example.com/"#).firstMatch(in: tainted) // BAD (incomplete hostname)
|
||||
_ = try Regex(#"^http[s]?://?sub1\.sub2\.example\.com/f/(.+)"#).firstMatch(in: tainted) // GOOD (it has a capture group after the TLD, so should be ignored)
|
||||
_ = try Regex(#"^https://[a-z]*.example.com$"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
|
||||
_ = try Regex(#"^(example.dev|example.com)"#).firstMatch(in: tainted) // $ Alert // GOOD (any extended hostname wouldn't be included in the capture group) [FALSE POSITIVE]
|
||||
_ = try Regex(#"^protos?://(localhost|.+.example.net|.+.example-a.com|.+.example-b.com|.+.example.internal)"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname x3, missing anchor x 1)
|
||||
_ = try Regex(#"^https://[a-z]*.example.com$"#).firstMatch(in: tainted) // BAD (incomplete hostname)
|
||||
_ = try Regex(#"^(example.dev|example.com)"#).firstMatch(in: tainted) // GOOD (any extended hostname wouldn't be included in the capture group) [FALSE POSITIVE]
|
||||
_ = try Regex(#"^protos?://(localhost|.+.example.net|.+.example-a.com|.+.example-b.com|.+.example.internal)"#).firstMatch(in: tainted) // BAD (incomplete hostname x3, missing anchor x 1)
|
||||
|
||||
_ = try Regex(#"^http://(..|...)\.example\.com/index\.html"#).firstMatch(in: tainted) // GOOD (wildcards are intentional)
|
||||
_ = try Regex(#"^http://.\.example\.com/index\.html"#).firstMatch(in: tainted) // GOOD (the wildcard is intentional)
|
||||
_ = try Regex(#"^(foo.example\.com|whatever)$"#).firstMatch(in: tainted) // $ Alert // DUBIOUS (one disjunction doesn't even look like a hostname) [DETECTED incomplete hostname, missing anchor]
|
||||
_ = try Regex(#"^(foo.example\.com|whatever)$"#).firstMatch(in: tainted) // DUBIOUS (one disjunction doesn't even look like a hostname) [DETECTED incomplete hostname, missing anchor]
|
||||
|
||||
_ = try Regex(#"^test.example.com$"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
|
||||
_ = try Regex(#"test.example.com"#).wholeMatch(in: tainted) // $ Alert // BAD (incomplete hostname, missing anchor)
|
||||
_ = try Regex(#"^test.example.com$"#).firstMatch(in: tainted) // BAD (incomplete hostname)
|
||||
_ = try Regex(#"test.example.com"#).wholeMatch(in: tainted) // BAD (incomplete hostname, missing anchor)
|
||||
|
||||
_ = try Regex(id(id(id(#"test.example.com$"#)))).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
|
||||
_ = try Regex(id(id(id(#"test.example.com$"#)))).firstMatch(in: tainted) // BAD (incomplete hostname)
|
||||
|
||||
let hostname = #"test.example.com$"# // BAD (incomplete hostname) [NOT DETECTED]
|
||||
_ = try Regex("\(hostname)").firstMatch(in: tainted)
|
||||
|
||||
var domain = MyDomain("")
|
||||
domain.hostname = #"test.example.com$"# // $ Alert // BAD (incomplete hostname)
|
||||
domain.hostname = #"test.example.com$"# // BAD (incomplete hostname)
|
||||
_ = try Regex(domain.hostname).firstMatch(in: tainted)
|
||||
|
||||
func convert1(_ domain: MyDomain) throws -> Regex<AnyRegexOutput> {
|
||||
return try Regex(domain.hostname)
|
||||
}
|
||||
_ = try convert1(MyDomain(#"test.example.com$"#)).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
|
||||
_ = try convert1(MyDomain(#"test.example.com$"#)).firstMatch(in: tainted) // BAD (incomplete hostname)
|
||||
|
||||
let domains = [ MyDomain(#"test.example.com$"#) ] // BAD (incomplete hostname) [NOT DETECTED]
|
||||
func convert2(_ domain: MyDomain) throws -> Regex<AnyRegexOutput> {
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
query: experimental/Security/CWE-022/UnsafeUnpack.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
experimental/Security/CWE-022/UnsafeUnpack.ql
|
||||
@@ -59,12 +59,12 @@ func testCommandInjectionQhelpExamples() {
|
||||
let source = URL(fileURLWithPath: "/sourcePath")
|
||||
let destination = URL(fileURLWithPath: "/destination")
|
||||
|
||||
try Data(contentsOf: remoteURL, options: []).write(to: source) // $ Source
|
||||
try Data(contentsOf: remoteURL, options: []).write(to: source)
|
||||
do {
|
||||
try Zip.unzipFile(source, destination: destination, overwrite: true, password: nil) // $ Alert
|
||||
try Zip.unzipFile(source, destination: destination, overwrite: true, password: nil) // BAD
|
||||
|
||||
let fileManager = FileManager()
|
||||
try fileManager.unzipItem(at: source, to: destination) // $ Alert
|
||||
try fileManager.unzipItem(at: source, to: destination) // BAD
|
||||
} catch {
|
||||
print("Error: \(error)")
|
||||
}
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
query: queries/Security/CWE-079/UnsafeWebViewFetch.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
queries/Security/CWE-079/UnsafeWebViewFetch.ql
|
||||
@@ -91,7 +91,7 @@ func getRemoteData() -> String {
|
||||
let url = URL(string: "http://example.com/")
|
||||
do
|
||||
{
|
||||
return try String(contentsOf: url!) // $ Source
|
||||
return try String(contentsOf: url!)
|
||||
} catch {
|
||||
return ""
|
||||
}
|
||||
@@ -100,13 +100,13 @@ func getRemoteData() -> String {
|
||||
func testSimpleFlows() {
|
||||
let webview = UIWebView()
|
||||
|
||||
webview.loadHTMLString(try! String(contentsOf: URL(string: "http://example.com/")!), baseURL: nil) // $ Alert
|
||||
webview.loadHTMLString(try! String(contentsOf: URL(string: "http://example.com/")!), baseURL: nil) // BAD
|
||||
|
||||
let data = try! String(contentsOf: URL(string: "http://example.com/")!) // $ Source
|
||||
webview.loadHTMLString(data, baseURL: nil) // $ Alert
|
||||
let data = try! String(contentsOf: URL(string: "http://example.com/")!)
|
||||
webview.loadHTMLString(data, baseURL: nil) // BAD
|
||||
|
||||
let url = URL(string: "http://example.com/")
|
||||
webview.loadHTMLString(try! String(contentsOf: url!), baseURL: nil) // $ Alert
|
||||
webview.loadHTMLString(try! String(contentsOf: url!), baseURL: nil) // BAD
|
||||
}
|
||||
|
||||
func testUIWebView() {
|
||||
@@ -117,14 +117,14 @@ func testUIWebView() {
|
||||
let remoteString = getRemoteData()
|
||||
|
||||
webview.loadHTMLString(localString, baseURL: nil) // GOOD: the HTML data is local
|
||||
webview.loadHTMLString(getRemoteData(), baseURL: nil) // $ Alert // BAD: HTML contains remote input, may access local secrets
|
||||
webview.loadHTMLString(remoteString, baseURL: nil) // $ Alert
|
||||
webview.loadHTMLString(getRemoteData(), baseURL: nil) // BAD: HTML contains remote input, may access local secrets
|
||||
webview.loadHTMLString(remoteString, baseURL: nil) // BAD
|
||||
|
||||
webview.loadHTMLString("<html>" + localStringFragment + "</html>", baseURL: nil) // GOOD: the HTML data is local
|
||||
webview.loadHTMLString("<html>" + remoteString + "</html>", baseURL: nil) // $ Alert
|
||||
webview.loadHTMLString("<html>" + remoteString + "</html>", baseURL: nil) // BAD
|
||||
|
||||
webview.loadHTMLString("<html>\(localStringFragment)</html>", baseURL: nil) // GOOD: the HTML data is local
|
||||
webview.loadHTMLString("<html>\(remoteString)</html>", baseURL: nil) // $ Alert
|
||||
webview.loadHTMLString("<html>\(remoteString)</html>", baseURL: nil) // BAD
|
||||
|
||||
let localSafeURL = URL(string: "about:blank")
|
||||
let localURL = URL(string: "http://example.com/")
|
||||
@@ -136,9 +136,9 @@ func testUIWebView() {
|
||||
webview.loadHTMLString(localString, baseURL: localURL!) // GOOD: a presumed safe baseURL is specified
|
||||
webview.loadHTMLString(remoteString, baseURL: localURL!) // GOOD: a presumed safe baseURL is specified
|
||||
webview.loadHTMLString(localString, baseURL: remoteURL!) // GOOD: the HTML data is local
|
||||
webview.loadHTMLString(remoteString, baseURL: remoteURL!) // $ Alert
|
||||
webview.loadHTMLString(remoteString, baseURL: remoteURL!) // BAD
|
||||
webview.loadHTMLString(localString, baseURL: remoteURL2!) // GOOD: the HTML data is local
|
||||
webview.loadHTMLString(remoteString, baseURL: remoteURL2!) // $ Alert
|
||||
webview.loadHTMLString(remoteString, baseURL: remoteURL2!) // BAD
|
||||
|
||||
let localRequest = URLRequest(url: localURL!)
|
||||
let remoteRequest = URLRequest(url: remoteURL!)
|
||||
@@ -151,7 +151,7 @@ func testUIWebView() {
|
||||
webview.load(localData, mimeType: "text/html", textEncodingName: "utf-8", baseURL: localSafeURL!) // GOOD: the data is local
|
||||
webview.load(remoteData, mimeType: "text/html", textEncodingName: "utf-8", baseURL: localSafeURL!) // GOOD: a safe baseURL is specified
|
||||
webview.load(localData, mimeType: "text/html", textEncodingName: "utf-8", baseURL: remoteURL!) // GOOD: the HTML data is local
|
||||
webview.load(remoteData, mimeType: "text/html", textEncodingName: "utf-8", baseURL: remoteURL!) // $ Alert
|
||||
webview.load(remoteData, mimeType: "text/html", textEncodingName: "utf-8", baseURL: remoteURL!) // BAD
|
||||
}
|
||||
|
||||
func testWKWebView() {
|
||||
@@ -164,14 +164,14 @@ func testWKWebView() {
|
||||
let remoteString = getRemoteData()
|
||||
|
||||
webview.loadHTMLString(localString, baseURL: nil) // GOOD: the HTML data is local
|
||||
webview.loadHTMLString(getRemoteData(), baseURL: nil) // $ Alert
|
||||
webview.loadHTMLString(remoteString, baseURL: nil) // $ Alert
|
||||
webview.loadHTMLString(getRemoteData(), baseURL: nil) // BAD
|
||||
webview.loadHTMLString(remoteString, baseURL: nil) // BAD
|
||||
|
||||
webview.loadHTMLString("<html>" + localStringFragment + "</html>", baseURL: nil) // GOOD: the HTML data is local
|
||||
webview.loadHTMLString("<html>" + remoteString + "</html>", baseURL: nil) // $ Alert
|
||||
webview.loadHTMLString("<html>" + remoteString + "</html>", baseURL: nil) // BAD
|
||||
|
||||
webview.loadHTMLString("<html>\(localStringFragment)</html>", baseURL: nil) // GOOD: the HTML data is local
|
||||
webview.loadHTMLString("<html>\(remoteString)</html>", baseURL: nil) // $ Alert
|
||||
webview.loadHTMLString("<html>\(remoteString)</html>", baseURL: nil) // BAD
|
||||
|
||||
let localSafeURL = URL(string: "about:blank")
|
||||
let localURL = URL(string: "http://example.com/")
|
||||
@@ -183,9 +183,9 @@ func testWKWebView() {
|
||||
webview.loadHTMLString(localString, baseURL: localURL!) // GOOD: a presumed safe baseURL is specified
|
||||
webview.loadHTMLString(remoteString, baseURL: localURL!) // GOOD: a presumed safe baseURL is specified
|
||||
webview.loadHTMLString(localString, baseURL: remoteURL!) // GOOD: the HTML data is local
|
||||
webview.loadHTMLString(remoteString, baseURL: remoteURL!) // $ Alert
|
||||
webview.loadHTMLString(remoteString, baseURL: remoteURL!) // BAD
|
||||
webview.loadHTMLString(localString, baseURL: remoteURL2!) // GOOD: the HTML data is local
|
||||
webview.loadHTMLString(remoteString, baseURL: remoteURL2!) // $ Alert
|
||||
webview.loadHTMLString(remoteString, baseURL: remoteURL2!) // BAD
|
||||
|
||||
let localRequest = URLRequest(url: localURL!)
|
||||
let remoteRequest = URLRequest(url: remoteURL!)
|
||||
@@ -198,7 +198,7 @@ func testWKWebView() {
|
||||
webview.load(localData, mimeType: "text/html", characterEncodingName: "utf-8", baseURL: localSafeURL!) // GOOD: the data is local
|
||||
webview.load(remoteData, mimeType: "text/html", characterEncodingName: "utf-8", baseURL: localSafeURL!) // GOOD: a safe baseURL is specified
|
||||
webview.load(localData, mimeType: "text/html", characterEncodingName: "utf-8", baseURL: remoteURL!) // GOOD: the HTML data is local
|
||||
webview.load(remoteData, mimeType: "text/html", characterEncodingName: "utf-8", baseURL: remoteURL!) // $ Alert
|
||||
webview.load(remoteData, mimeType: "text/html", characterEncodingName: "utf-8", baseURL: remoteURL!) // BAD
|
||||
}
|
||||
|
||||
func testQHelpExamples() {
|
||||
@@ -207,7 +207,7 @@ func testQHelpExamples() {
|
||||
|
||||
// ...
|
||||
|
||||
webview.loadHTMLString(htmlData, baseURL: nil) // $ Alert
|
||||
webview.loadHTMLString(htmlData, baseURL: nil) // BAD
|
||||
webview.loadHTMLString(htmlData, baseURL: URL(string: "about:blank")) // GOOD
|
||||
}
|
||||
|
||||
|
||||
@@ -101,54 +101,54 @@ class CommonTableExpression {
|
||||
|
||||
func test(database: Database) throws {
|
||||
let localString = "user"
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
|
||||
|
||||
let _ = database.allStatements(sql: remoteString) // $ Alert
|
||||
let _ = database.allStatements(sql: remoteString) // BAD
|
||||
let _ = database.allStatements(sql: localString) // GOOD
|
||||
let _ = database.allStatements(sql: remoteString, arguments: nil) // $ Alert
|
||||
let _ = database.allStatements(sql: remoteString, arguments: nil) // BAD
|
||||
let _ = database.allStatements(sql: localString, arguments: nil) // GOOD
|
||||
|
||||
let _ = database.cachedStatement(sql: remoteString) // $ Alert
|
||||
let _ = database.cachedStatement(sql: remoteString) // BAD
|
||||
let _ = database.cachedStatement(sql: localString) // GOOD
|
||||
|
||||
let _ = database.internalCachedStatement(sql: remoteString) // $ Alert
|
||||
let _ = database.internalCachedStatement(sql: remoteString) // BAD
|
||||
let _ = database.internalCachedStatement(sql: localString) // GOOD
|
||||
|
||||
database.execute(sql: remoteString) // $ Alert
|
||||
database.execute(sql: remoteString) // BAD
|
||||
database.execute(sql: localString) // GOOD
|
||||
database.execute(sql: remoteString, arguments: StatementArguments()) // $ Alert
|
||||
database.execute(sql: remoteString, arguments: StatementArguments()) // BAD
|
||||
database.execute(sql: localString, arguments: StatementArguments()) // GOOD
|
||||
|
||||
let _ = database.makeStatement(sql: remoteString) // $ Alert
|
||||
let _ = database.makeStatement(sql: remoteString) // BAD
|
||||
let _ = database.makeStatement(sql: localString) // GOOD
|
||||
let _ = database.makeStatement(sql: remoteString, prepFlags: 0) // $ Alert
|
||||
let _ = database.makeStatement(sql: remoteString, prepFlags: 0) // BAD
|
||||
let _ = database.makeStatement(sql: localString, prepFlags: 0) // GOOD
|
||||
}
|
||||
|
||||
func testSqlRequest() throws {
|
||||
let localString = "user"
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
|
||||
|
||||
let _ = SQLRequest(stringLiteral: remoteString) // $ Alert
|
||||
let _ = SQLRequest(stringLiteral: remoteString) // BAD
|
||||
let _ = SQLRequest(stringLiteral: localString) // GOOD
|
||||
|
||||
let _ = SQLRequest(unicodeScalarLiteral: remoteString) // $ Alert
|
||||
let _ = SQLRequest(unicodeScalarLiteral: remoteString) // BAD
|
||||
let _ = SQLRequest(unicodeScalarLiteral: localString) // GOOD
|
||||
|
||||
let _ = SQLRequest(extendedGraphemeClusterLiteral: remoteString) // $ Alert
|
||||
let _ = SQLRequest(extendedGraphemeClusterLiteral: remoteString) // BAD
|
||||
let _ = SQLRequest(extendedGraphemeClusterLiteral: localString) // GOOD
|
||||
|
||||
let _ = SQLRequest(stringInterpolation: remoteString) // $ Alert
|
||||
let _ = SQLRequest(stringInterpolation: remoteString) // BAD
|
||||
let _ = SQLRequest(stringInterpolation: localString) // GOOD
|
||||
|
||||
let _ = SQLRequest(sql: remoteString) // $ Alert
|
||||
let _ = SQLRequest(sql: remoteString, arguments: StatementArguments()) // $ Alert
|
||||
let _ = SQLRequest(sql: remoteString, arguments: StatementArguments(), adapter: nil) // $ Alert
|
||||
let _ = SQLRequest(sql: remoteString, arguments: StatementArguments(), cached: false) // $ Alert
|
||||
let _ = SQLRequest(sql: remoteString, arguments: StatementArguments(), adapter: nil, cached: false) // $ Alert
|
||||
let _ = SQLRequest(sql: remoteString, adapter: nil) // $ Alert
|
||||
let _ = SQLRequest(sql: remoteString, adapter: nil, cached: false) // $ Alert
|
||||
let _ = SQLRequest(sql: remoteString, cached: false) // $ Alert
|
||||
let _ = SQLRequest(sql: remoteString) // BAD
|
||||
let _ = SQLRequest(sql: remoteString, arguments: StatementArguments()) // BAD
|
||||
let _ = SQLRequest(sql: remoteString, arguments: StatementArguments(), adapter: nil) // BAD
|
||||
let _ = SQLRequest(sql: remoteString, arguments: StatementArguments(), cached: false) // BAD
|
||||
let _ = SQLRequest(sql: remoteString, arguments: StatementArguments(), adapter: nil, cached: false) // BAD
|
||||
let _ = SQLRequest(sql: remoteString, adapter: nil) // BAD
|
||||
let _ = SQLRequest(sql: remoteString, adapter: nil, cached: false) // BAD
|
||||
let _ = SQLRequest(sql: remoteString, cached: false) // BAD
|
||||
let _ = SQLRequest(sql: localString) // GOOD
|
||||
let _ = SQLRequest(sql: localString, arguments: StatementArguments()) // GOOD
|
||||
let _ = SQLRequest(sql: localString, arguments: StatementArguments(), adapter: nil) // GOOD
|
||||
@@ -161,15 +161,15 @@ func testSqlRequest() throws {
|
||||
|
||||
func testSql() throws {
|
||||
let localString = "user"
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
|
||||
|
||||
let _ = SQL(stringLiteral: remoteString) // $ Alert
|
||||
let _ = SQL(unicodeScalarLiteral: remoteString) // $ Alert
|
||||
let _ = SQL(extendedGraphemeClusterLiteral: remoteString) // $ Alert
|
||||
let _ = SQL(stringInterpolation: remoteString) // $ Alert
|
||||
let _ = SQL(sql: remoteString) // $ Alert
|
||||
let _ = SQL(stringLiteral: remoteString) // BAD
|
||||
let _ = SQL(unicodeScalarLiteral: remoteString) // BAD
|
||||
let _ = SQL(extendedGraphemeClusterLiteral: remoteString) // BAD
|
||||
let _ = SQL(stringInterpolation: remoteString) // BAD
|
||||
let _ = SQL(sql: remoteString) // BAD
|
||||
let sql1 = SQL(stringLiteral: "")
|
||||
sql1.append(sql: remoteString) // $ Alert
|
||||
sql1.append(sql: remoteString) // BAD
|
||||
|
||||
let _ = SQL(stringLiteral: localString) // GOOD
|
||||
let _ = SQL(unicodeScalarLiteral: localString) // GOOD
|
||||
@@ -182,34 +182,34 @@ func testSql() throws {
|
||||
|
||||
func test(tableDefinition: TableDefinition) throws {
|
||||
let localString = "user"
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
|
||||
|
||||
tableDefinition.column(sql: remoteString) // $ Alert
|
||||
tableDefinition.column(sql: remoteString) // BAD
|
||||
tableDefinition.column(sql: localString) // GOOD
|
||||
|
||||
tableDefinition.check(sql: remoteString) // $ Alert
|
||||
tableDefinition.check(sql: remoteString) // BAD
|
||||
tableDefinition.check(sql: localString) // GOOD
|
||||
|
||||
tableDefinition.constraint(sql: remoteString) // $ Alert
|
||||
tableDefinition.constraint(sql: remoteString) // BAD
|
||||
tableDefinition.constraint(sql: localString) // GOOD
|
||||
}
|
||||
|
||||
func test(tableAlteration: TableAlteration) throws {
|
||||
let localString = "user"
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
|
||||
|
||||
tableAlteration.addColumn(sql: remoteString) // $ Alert
|
||||
tableAlteration.addColumn(sql: remoteString) // BAD
|
||||
tableAlteration.addColumn(sql: localString) // GOOD
|
||||
}
|
||||
|
||||
func test(columnDefinition: ColumnDefinition) throws {
|
||||
let localString = "user"
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
|
||||
|
||||
let _ = columnDefinition.check(sql: remoteString) // $ Alert
|
||||
let _ = columnDefinition.defaults(sql: remoteString) // $ Alert
|
||||
let _ = columnDefinition.generatedAs(sql: remoteString) // $ Alert
|
||||
let _ = columnDefinition.generatedAs(sql: remoteString, .virtual) // $ Alert
|
||||
let _ = columnDefinition.check(sql: remoteString) // BAD
|
||||
let _ = columnDefinition.defaults(sql: remoteString) // BAD
|
||||
let _ = columnDefinition.generatedAs(sql: remoteString) // BAD
|
||||
let _ = columnDefinition.generatedAs(sql: remoteString, .virtual) // BAD
|
||||
|
||||
let _ = columnDefinition.check(sql: localString) // GOOD
|
||||
let _ = columnDefinition.defaults(sql: localString) // GOOD
|
||||
@@ -219,67 +219,67 @@ func test(columnDefinition: ColumnDefinition) throws {
|
||||
|
||||
func testTableRecord() throws {
|
||||
let localString = "user"
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
|
||||
|
||||
let _ = TableRecord.select(sql: remoteString) // $ Alert
|
||||
let _ = TableRecord.select(sql: remoteString, arguments: StatementArguments()) // $ Alert
|
||||
let _ = TableRecord.select(sql: remoteString) // BAD
|
||||
let _ = TableRecord.select(sql: remoteString, arguments: StatementArguments()) // BAD
|
||||
let _ = TableRecord.select(sql: localString) // GOOD
|
||||
let _ = TableRecord.select(sql: localString, arguments: StatementArguments()) // GOOD
|
||||
|
||||
let _ = TableRecord.filter(sql: remoteString) // $ Alert
|
||||
let _ = TableRecord.filter(sql: remoteString, arguments: StatementArguments()) // $ Alert
|
||||
let _ = TableRecord.filter(sql: remoteString) // BAD
|
||||
let _ = TableRecord.filter(sql: remoteString, arguments: StatementArguments()) // BAD
|
||||
let _ = TableRecord.filter(sql: localString) // GOOD
|
||||
let _ = TableRecord.filter(sql: localString, arguments: StatementArguments()) // GOOD
|
||||
|
||||
let _ = TableRecord.order(sql: remoteString) // $ Alert
|
||||
let _ = TableRecord.order(sql: remoteString, arguments: StatementArguments()) // $ Alert
|
||||
let _ = TableRecord.order(sql: remoteString) // BAD
|
||||
let _ = TableRecord.order(sql: remoteString, arguments: StatementArguments()) // BAD
|
||||
let _ = TableRecord.order(sql: localString) // GOOD
|
||||
let _ = TableRecord.order(sql: localString, arguments: StatementArguments()) // GOOD
|
||||
}
|
||||
|
||||
func test(statementCache: StatementCache) throws {
|
||||
let localString = "user"
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
|
||||
|
||||
let _ = statementCache.statement(remoteString) // $ Alert
|
||||
let _ = statementCache.statement(remoteString) // BAD
|
||||
let _ = statementCache.statement(localString) // GOOD
|
||||
}
|
||||
|
||||
func test(row: Row, stmt: Statement) throws {
|
||||
let localString = "user"
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
|
||||
|
||||
row.fetchCursor(stmt, sql: remoteString) // $ Alert
|
||||
row.fetchCursor(stmt, sql: remoteString, arguments: StatementArguments()) // $ Alert
|
||||
row.fetchCursor(stmt, sql: remoteString, adapter: nil) // $ Alert
|
||||
row.fetchCursor(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // $ Alert
|
||||
row.fetchCursor(stmt, sql: remoteString) // BAD
|
||||
row.fetchCursor(stmt, sql: remoteString, arguments: StatementArguments()) // BAD
|
||||
row.fetchCursor(stmt, sql: remoteString, adapter: nil) // BAD
|
||||
row.fetchCursor(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // BAD
|
||||
row.fetchCursor(stmt, sql: localString) // GOOD
|
||||
row.fetchCursor(stmt, sql: localString, arguments: StatementArguments()) // GOOD
|
||||
row.fetchCursor(stmt, sql: localString, adapter: nil) // GOOD
|
||||
row.fetchCursor(stmt, sql: localString, arguments: StatementArguments(), adapter: nil) // GOOD
|
||||
|
||||
row.fetchAll(stmt, sql: remoteString) // $ Alert
|
||||
row.fetchAll(stmt, sql: remoteString, arguments: StatementArguments()) // $ Alert
|
||||
row.fetchAll(stmt, sql: remoteString, adapter: nil) // $ Alert
|
||||
row.fetchAll(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // $ Alert
|
||||
row.fetchAll(stmt, sql: remoteString) // BAD
|
||||
row.fetchAll(stmt, sql: remoteString, arguments: StatementArguments()) // BAD
|
||||
row.fetchAll(stmt, sql: remoteString, adapter: nil) // BAD
|
||||
row.fetchAll(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // BAD
|
||||
row.fetchAll(stmt, sql: localString) // GOOD
|
||||
row.fetchAll(stmt, sql: localString, arguments: StatementArguments()) // GOOD
|
||||
row.fetchAll(stmt, sql: localString, adapter: nil) // GOOD
|
||||
row.fetchAll(stmt, sql: localString, arguments: StatementArguments(), adapter: nil) // GOOD
|
||||
|
||||
row.fetchOne(stmt, sql: remoteString) // $ Alert
|
||||
row.fetchOne(stmt, sql: remoteString, arguments: StatementArguments()) // $ Alert
|
||||
row.fetchOne(stmt, sql: remoteString, adapter: nil) // $ Alert
|
||||
row.fetchOne(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // $ Alert
|
||||
row.fetchOne(stmt, sql: remoteString) // BAD
|
||||
row.fetchOne(stmt, sql: remoteString, arguments: StatementArguments()) // BAD
|
||||
row.fetchOne(stmt, sql: remoteString, adapter: nil) // BAD
|
||||
row.fetchOne(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // BAD
|
||||
row.fetchOne(stmt, sql: localString) // GOOD
|
||||
row.fetchOne(stmt, sql: localString, arguments: StatementArguments()) // GOOD
|
||||
row.fetchOne(stmt, sql: localString, adapter: nil) // GOOD
|
||||
row.fetchOne(stmt, sql: localString, arguments: StatementArguments(), adapter: nil) // GOOD
|
||||
|
||||
row.fetchSet(stmt, sql: remoteString) // $ Alert
|
||||
row.fetchSet(stmt, sql: remoteString, arguments: StatementArguments()) // $ Alert
|
||||
row.fetchSet(stmt, sql: remoteString, adapter: nil) // $ Alert
|
||||
row.fetchSet(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // $ Alert
|
||||
row.fetchSet(stmt, sql: remoteString) // BAD
|
||||
row.fetchSet(stmt, sql: remoteString, arguments: StatementArguments()) // BAD
|
||||
row.fetchSet(stmt, sql: remoteString, adapter: nil) // BAD
|
||||
row.fetchSet(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // BAD
|
||||
row.fetchSet(stmt, sql: localString) // GOOD
|
||||
row.fetchSet(stmt, sql: localString, arguments: StatementArguments()) // GOOD
|
||||
row.fetchSet(stmt, sql: localString, adapter: nil) // GOOD
|
||||
@@ -288,39 +288,39 @@ func test(row: Row, stmt: Statement) throws {
|
||||
|
||||
func test(databaseValueConvertible: DatabaseValueConvertible, stmt: Statement) throws {
|
||||
let localString = "user"
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
|
||||
|
||||
databaseValueConvertible.fetchCursor(stmt, sql: remoteString) // $ Alert
|
||||
databaseValueConvertible.fetchCursor(stmt, sql: remoteString, arguments: StatementArguments()) // $ Alert
|
||||
databaseValueConvertible.fetchCursor(stmt, sql: remoteString, adapter: nil) // $ Alert
|
||||
databaseValueConvertible.fetchCursor(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // $ Alert
|
||||
databaseValueConvertible.fetchCursor(stmt, sql: remoteString) // BAD
|
||||
databaseValueConvertible.fetchCursor(stmt, sql: remoteString, arguments: StatementArguments()) // BAD
|
||||
databaseValueConvertible.fetchCursor(stmt, sql: remoteString, adapter: nil) // BAD
|
||||
databaseValueConvertible.fetchCursor(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // BAD
|
||||
databaseValueConvertible.fetchCursor(stmt, sql: localString) // GOOD
|
||||
databaseValueConvertible.fetchCursor(stmt, sql: localString, arguments: StatementArguments()) // GOOD
|
||||
databaseValueConvertible.fetchCursor(stmt, sql: localString, adapter: nil) // GOOD
|
||||
databaseValueConvertible.fetchCursor(stmt, sql: localString, arguments: StatementArguments(), adapter: nil) // GOOD
|
||||
|
||||
databaseValueConvertible.fetchAll(stmt, sql: remoteString) // $ Alert
|
||||
databaseValueConvertible.fetchAll(stmt, sql: remoteString, arguments: StatementArguments()) // $ Alert
|
||||
databaseValueConvertible.fetchAll(stmt, sql: remoteString, adapter: nil) // $ Alert
|
||||
databaseValueConvertible.fetchAll(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // $ Alert
|
||||
databaseValueConvertible.fetchAll(stmt, sql: remoteString) // BAD
|
||||
databaseValueConvertible.fetchAll(stmt, sql: remoteString, arguments: StatementArguments()) // BAD
|
||||
databaseValueConvertible.fetchAll(stmt, sql: remoteString, adapter: nil) // BAD
|
||||
databaseValueConvertible.fetchAll(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // BAD
|
||||
databaseValueConvertible.fetchAll(stmt, sql: localString) // GOOD
|
||||
databaseValueConvertible.fetchAll(stmt, sql: localString, arguments: StatementArguments()) // GOOD
|
||||
databaseValueConvertible.fetchAll(stmt, sql: localString, adapter: nil) // GOOD
|
||||
databaseValueConvertible.fetchAll(stmt, sql: localString, arguments: StatementArguments(), adapter: nil) // GOOD
|
||||
|
||||
databaseValueConvertible.fetchOne(stmt, sql: remoteString) // $ Alert
|
||||
databaseValueConvertible.fetchOne(stmt, sql: remoteString, arguments: StatementArguments()) // $ Alert
|
||||
databaseValueConvertible.fetchOne(stmt, sql: remoteString, adapter: nil) // $ Alert
|
||||
databaseValueConvertible.fetchOne(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // $ Alert
|
||||
databaseValueConvertible.fetchOne(stmt, sql: remoteString) // BAD
|
||||
databaseValueConvertible.fetchOne(stmt, sql: remoteString, arguments: StatementArguments()) // BAD
|
||||
databaseValueConvertible.fetchOne(stmt, sql: remoteString, adapter: nil) // BAD
|
||||
databaseValueConvertible.fetchOne(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // BAD
|
||||
databaseValueConvertible.fetchOne(stmt, sql: localString) // GOOD
|
||||
databaseValueConvertible.fetchOne(stmt, sql: localString, arguments: StatementArguments()) // GOOD
|
||||
databaseValueConvertible.fetchOne(stmt, sql: localString, adapter: nil) // GOOD
|
||||
databaseValueConvertible.fetchOne(stmt, sql: localString, arguments: StatementArguments(), adapter: nil) // GOOD
|
||||
|
||||
databaseValueConvertible.fetchSet(stmt, sql: remoteString) // $ Alert
|
||||
databaseValueConvertible.fetchSet(stmt, sql: remoteString, arguments: StatementArguments()) // $ Alert
|
||||
databaseValueConvertible.fetchSet(stmt, sql: remoteString, adapter: nil) // $ Alert
|
||||
databaseValueConvertible.fetchSet(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // $ Alert
|
||||
databaseValueConvertible.fetchSet(stmt, sql: remoteString) // BAD
|
||||
databaseValueConvertible.fetchSet(stmt, sql: remoteString, arguments: StatementArguments()) // BAD
|
||||
databaseValueConvertible.fetchSet(stmt, sql: remoteString, adapter: nil) // BAD
|
||||
databaseValueConvertible.fetchSet(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // BAD
|
||||
databaseValueConvertible.fetchSet(stmt, sql: localString) // GOOD
|
||||
databaseValueConvertible.fetchSet(stmt, sql: localString, arguments: StatementArguments()) // GOOD
|
||||
databaseValueConvertible.fetchSet(stmt, sql: localString, adapter: nil) // GOOD
|
||||
@@ -329,26 +329,26 @@ func test(databaseValueConvertible: DatabaseValueConvertible, stmt: Statement) t
|
||||
|
||||
func testSqlStatementCursor(database: Database) throws {
|
||||
let localString = "user"
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
|
||||
|
||||
let _ = SQLStatementCursor(database: database, sql: remoteString, arguments: StatementArguments()) // $ Alert
|
||||
let _ = SQLStatementCursor(database: database, sql: remoteString, arguments: StatementArguments(), prepFlags: 0) // $ Alert
|
||||
let _ = SQLStatementCursor(database: database, sql: remoteString, arguments: StatementArguments()) // BAD
|
||||
let _ = SQLStatementCursor(database: database, sql: remoteString, arguments: StatementArguments(), prepFlags: 0) // BAD
|
||||
let _ = SQLStatementCursor(database: database, sql: localString, arguments: StatementArguments()) // GOOD
|
||||
let _ = SQLStatementCursor(database: database, sql: localString, arguments: StatementArguments(), prepFlags: 0) // GOOD
|
||||
}
|
||||
|
||||
func testCommonTableExpression() throws {
|
||||
let localString = "user"
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
|
||||
|
||||
let _ = CommonTableExpression(named: "", sql: remoteString) // $ Alert
|
||||
let _ = CommonTableExpression(named: "", sql: remoteString, arguments: StatementArguments()) // $ Alert
|
||||
let _ = CommonTableExpression(named: "", columns: [""], sql: remoteString) // $ Alert
|
||||
let _ = CommonTableExpression(named: "", columns: [""], sql: remoteString, arguments: StatementArguments()) // $ Alert
|
||||
let _ = CommonTableExpression(recursive: false, named: "", sql: remoteString) // $ Alert
|
||||
let _ = CommonTableExpression(recursive: false, named: "", columns: [""], sql: remoteString) // $ Alert
|
||||
let _ = CommonTableExpression(recursive: false, named: "", sql: remoteString, arguments: StatementArguments()) // $ Alert
|
||||
let _ = CommonTableExpression(recursive: false, named: "", columns: [""], sql: remoteString, arguments: StatementArguments()) // $ Alert
|
||||
let _ = CommonTableExpression(named: "", sql: remoteString) // BAD
|
||||
let _ = CommonTableExpression(named: "", sql: remoteString, arguments: StatementArguments()) // BAD
|
||||
let _ = CommonTableExpression(named: "", columns: [""], sql: remoteString) // BAD
|
||||
let _ = CommonTableExpression(named: "", columns: [""], sql: remoteString, arguments: StatementArguments()) // BAD
|
||||
let _ = CommonTableExpression(recursive: false, named: "", sql: remoteString) // BAD
|
||||
let _ = CommonTableExpression(recursive: false, named: "", columns: [""], sql: remoteString) // BAD
|
||||
let _ = CommonTableExpression(recursive: false, named: "", sql: remoteString, arguments: StatementArguments()) // BAD
|
||||
let _ = CommonTableExpression(recursive: false, named: "", columns: [""], sql: remoteString, arguments: StatementArguments()) // BAD
|
||||
let _ = CommonTableExpression(named: "", sql: localString) // GOOD
|
||||
let _ = CommonTableExpression(named: "", sql: localString, arguments: StatementArguments()) // GOOD
|
||||
let _ = CommonTableExpression(named: "", columns: [""], sql: localString) // GOOD
|
||||
|
||||
@@ -59,7 +59,7 @@ class Connection {
|
||||
|
||||
func test_sqlite_swift_api(db: Connection) throws {
|
||||
let localString = "user"
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
|
||||
let remoteNumber = Int(remoteString) ?? 0
|
||||
|
||||
let unsafeQuery1 = remoteString
|
||||
@@ -70,9 +70,9 @@ func test_sqlite_swift_api(db: Connection) throws {
|
||||
|
||||
// --- execute ---
|
||||
|
||||
try db.execute(unsafeQuery1) // $ Alert
|
||||
try db.execute(unsafeQuery2) // $ Alert
|
||||
try db.execute(unsafeQuery3) // $ Alert
|
||||
try db.execute(unsafeQuery1) // BAD
|
||||
try db.execute(unsafeQuery2) // BAD
|
||||
try db.execute(unsafeQuery3) // BAD
|
||||
try db.execute(safeQuery1) // GOOD
|
||||
try db.execute(safeQuery2) // GOOD
|
||||
|
||||
@@ -80,7 +80,7 @@ func test_sqlite_swift_api(db: Connection) throws {
|
||||
|
||||
let varQuery = "SELECT * FROM users WHERE username=?"
|
||||
|
||||
let stmt1 = try db.prepare(unsafeQuery3) // $ Alert
|
||||
let stmt1 = try db.prepare(unsafeQuery3) // BAD
|
||||
try stmt1.run()
|
||||
|
||||
let stmt2 = try db.prepare(varQuery, localString) // GOOD
|
||||
@@ -92,31 +92,31 @@ func test_sqlite_swift_api(db: Connection) throws {
|
||||
let stmt4 = try Statement(db, localString) // GOOD
|
||||
try stmt4.run()
|
||||
|
||||
let stmt5 = try Statement(db, remoteString) // $ Alert
|
||||
let stmt5 = try Statement(db, remoteString) // BAD
|
||||
try stmt5.run()
|
||||
|
||||
// --- more variants ---
|
||||
|
||||
let stmt6 = try db.prepare(unsafeQuery1, "") // $ Alert
|
||||
let stmt6 = try db.prepare(unsafeQuery1, "") // BAD
|
||||
try stmt6.run()
|
||||
|
||||
let stmt7 = try db.prepare(unsafeQuery1, [""]) // $ Alert
|
||||
let stmt7 = try db.prepare(unsafeQuery1, [""]) // BAD
|
||||
try stmt7.run()
|
||||
|
||||
let stmt8 = try db.prepare(unsafeQuery1, ["username": ""]) // $ Alert
|
||||
let stmt8 = try db.prepare(unsafeQuery1, ["username": ""]) // BAD
|
||||
try stmt8.run()
|
||||
|
||||
try db.run(unsafeQuery1, "") // $ Alert
|
||||
try db.run(unsafeQuery1, "") // BAD
|
||||
|
||||
try db.run(unsafeQuery1, [""]) // $ Alert
|
||||
try db.run(unsafeQuery1, [""]) // BAD
|
||||
|
||||
try db.run(unsafeQuery1, ["username": ""]) // $ Alert
|
||||
try db.run(unsafeQuery1, ["username": ""]) // BAD
|
||||
|
||||
try db.scalar(unsafeQuery1, "") // $ Alert
|
||||
try db.scalar(unsafeQuery1, "") // BAD
|
||||
|
||||
try db.scalar(unsafeQuery1, [""]) // $ Alert
|
||||
try db.scalar(unsafeQuery1, [""]) // BAD
|
||||
|
||||
try db.scalar(unsafeQuery1, ["username": ""]) // $ Alert
|
||||
try db.scalar(unsafeQuery1, ["username": ""]) // BAD
|
||||
|
||||
let stmt9 = try db.prepare(varQuery) // GOOD
|
||||
try stmt9.bind(remoteString) // GOOD
|
||||
@@ -129,5 +129,5 @@ func test_sqlite_swift_api(db: Connection) throws {
|
||||
try stmt9.scalar([remoteString]) // GOOD
|
||||
try stmt9.scalar(["username": remoteString]) // GOOD
|
||||
|
||||
try Statement(db, remoteString).run() // $ Alert
|
||||
try Statement(db, remoteString).run() // BAD
|
||||
}
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
query: queries/Security/CWE-089/SqlInjection.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
queries/Security/CWE-089/SqlInjection.ql
|
||||
@@ -43,18 +43,18 @@ class MyDatabase {
|
||||
// --- tests ---
|
||||
|
||||
func test_heuristic(db: MyDatabase) throws {
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
|
||||
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
|
||||
|
||||
_ = MyDatabase() // GOOD
|
||||
_ = MyDatabase(sql: "some_fixed_sql") // GOOD
|
||||
_ = MyDatabase(sql: remoteString) // $ Alert
|
||||
_ = MyDatabase(sql: remoteString) // BAD
|
||||
|
||||
db.execute1(remoteString) // $ Alert
|
||||
db.execute2(remoteString) // $ Alert
|
||||
db.execute3(NSString(string: remoteString)) // $ Alert
|
||||
db.execute4(remoteString as! Sql) // $ Alert
|
||||
db.execute1(remoteString) // BAD
|
||||
db.execute2(remoteString) // BAD
|
||||
db.execute3(NSString(string: remoteString)) // BAD
|
||||
db.execute4(remoteString as! Sql) // BAD
|
||||
|
||||
db.query(sql: remoteString) // $ Alert
|
||||
db.query(sql: remoteString) // BAD
|
||||
db.query(sqlLiteral: remoteString) // BAD [NOT DETECTED]
|
||||
db.query(sqlStatement: remoteString) // BAD [NOT DETECTED]
|
||||
db.query(sqliteStatement: remoteString) // BAD [NOT DETECTED]
|
||||
|
||||
@@ -119,7 +119,7 @@ func sqlite3_finalize(
|
||||
|
||||
func test_sqlite3_c_api(db: OpaquePointer?, buffer: UnsafeMutablePointer<UInt8>) {
|
||||
let localString = "user"
|
||||
let remoteString = try! String(contentsOf: URL(string: "http://example.com/")!) // $ Source
|
||||
let remoteString = try! String(contentsOf: URL(string: "http://example.com/")!)
|
||||
let remoteNumber = Int(remoteString) ?? 0
|
||||
|
||||
let unsafeQuery1 = remoteString
|
||||
@@ -130,9 +130,9 @@ func test_sqlite3_c_api(db: OpaquePointer?, buffer: UnsafeMutablePointer<UInt8>)
|
||||
|
||||
// --- exec ---
|
||||
|
||||
let result1 = sqlite3_exec(db, unsafeQuery1, nil, nil, nil) // $ Alert
|
||||
let result2 = sqlite3_exec(db, unsafeQuery2, nil, nil, nil) // $ Alert
|
||||
let result3 = sqlite3_exec(db, unsafeQuery3, nil, nil, nil) // $ Alert
|
||||
let result1 = sqlite3_exec(db, unsafeQuery1, nil, nil, nil) // BAD
|
||||
let result2 = sqlite3_exec(db, unsafeQuery2, nil, nil, nil) // BAD
|
||||
let result3 = sqlite3_exec(db, unsafeQuery3, nil, nil, nil) // BAD
|
||||
let result4 = sqlite3_exec(db, safeQuery1, nil, nil, nil) // GOOD
|
||||
let result5 = sqlite3_exec(db, safeQuery2, nil, nil, nil) // GOOD
|
||||
|
||||
@@ -142,7 +142,7 @@ func test_sqlite3_c_api(db: OpaquePointer?, buffer: UnsafeMutablePointer<UInt8>)
|
||||
|
||||
var stmt1: OpaquePointer?
|
||||
|
||||
if (sqlite3_prepare(db, unsafeQuery3, -1, &stmt1, nil) == SQLITE_OK) { // $ Alert
|
||||
if (sqlite3_prepare(db, unsafeQuery3, -1, &stmt1, nil) == SQLITE_OK) { // BAD
|
||||
let result = sqlite3_step(stmt1)
|
||||
// ...
|
||||
}
|
||||
@@ -172,7 +172,7 @@ func test_sqlite3_c_api(db: OpaquePointer?, buffer: UnsafeMutablePointer<UInt8>)
|
||||
|
||||
var stmt4: OpaquePointer?
|
||||
|
||||
if (sqlite3_prepare_v2(db, unsafeQuery3, -1, &stmt4, nil) == SQLITE_OK) { // $ Alert
|
||||
if (sqlite3_prepare_v2(db, unsafeQuery3, -1, &stmt4, nil) == SQLITE_OK) { // BAD
|
||||
let result = sqlite3_step(stmt4)
|
||||
// ...
|
||||
}
|
||||
@@ -180,7 +180,7 @@ func test_sqlite3_c_api(db: OpaquePointer?, buffer: UnsafeMutablePointer<UInt8>)
|
||||
|
||||
var stmt5: OpaquePointer?
|
||||
|
||||
if (sqlite3_prepare_v3(db, unsafeQuery3, -1, 0, &stmt5, nil) == SQLITE_OK) { // $ Alert
|
||||
if (sqlite3_prepare_v3(db, unsafeQuery3, -1, 0, &stmt5, nil) == SQLITE_OK) { // BAD
|
||||
let result = sqlite3_step(stmt5)
|
||||
// ...
|
||||
}
|
||||
@@ -191,7 +191,7 @@ func test_sqlite3_c_api(db: OpaquePointer?, buffer: UnsafeMutablePointer<UInt8>)
|
||||
|
||||
var stmt6: OpaquePointer?
|
||||
|
||||
if (sqlite3_prepare16(db, buffer, Int32(data.count), &stmt6, nil) == SQLITE_OK) { // $ Alert
|
||||
if (sqlite3_prepare16(db, buffer, Int32(data.count), &stmt6, nil) == SQLITE_OK) { // BAD
|
||||
let result = sqlite3_step(stmt6)
|
||||
// ...
|
||||
}
|
||||
@@ -199,7 +199,7 @@ func test_sqlite3_c_api(db: OpaquePointer?, buffer: UnsafeMutablePointer<UInt8>)
|
||||
|
||||
var stmt7: OpaquePointer?
|
||||
|
||||
if (sqlite3_prepare16_v2(db, buffer, Int32(data.count), &stmt7, nil) == SQLITE_OK) { // $ Alert
|
||||
if (sqlite3_prepare16_v2(db, buffer, Int32(data.count), &stmt7, nil) == SQLITE_OK) { // BAD
|
||||
let result = sqlite3_step(stmt7)
|
||||
// ...
|
||||
}
|
||||
@@ -207,7 +207,7 @@ func test_sqlite3_c_api(db: OpaquePointer?, buffer: UnsafeMutablePointer<UInt8>)
|
||||
|
||||
var stmt8: OpaquePointer?
|
||||
|
||||
if (sqlite3_prepare16_v3(db, buffer, Int32(data.count), 0, &stmt8, nil) == SQLITE_OK) { // $ Alert
|
||||
if (sqlite3_prepare16_v3(db, buffer, Int32(data.count), 0, &stmt8, nil) == SQLITE_OK) { // BAD
|
||||
let result = sqlite3_step(stmt8)
|
||||
// ...
|
||||
}
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
query: queries/Security/CWE-116/BadTagFilter.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
queries/Security/CWE-116/BadTagFilter.ql
|
||||
@@ -76,18 +76,18 @@ func myRegexpVariantsTests(myUrl: URL) throws {
|
||||
let tainted = String(contentsOf: myUrl) // tainted
|
||||
|
||||
// BAD - doesn't match newlines or `</script >`
|
||||
let re1 = try Regex(#"<script.*?>.*?<\/script>"#).ignoresCase(true) // $ Alert
|
||||
let re1 = try Regex(#"<script.*?>.*?<\/script>"#).ignoresCase(true)
|
||||
_ = try re1.firstMatch(in: tainted)
|
||||
|
||||
// BAD - doesn't match `</script >`
|
||||
let re2a = try Regex(#"(?is)<script.*?>.*?<\/script>"#) // $ Alert
|
||||
let re2a = try Regex(#"(?is)<script.*?>.*?<\/script>"#)
|
||||
_ = try re2a.firstMatch(in: tainted)
|
||||
// BAD - doesn't match `</script >`
|
||||
let re2b = try Regex(#"<script.*?>.*?<\/script>"#).ignoresCase(true).dotMatchesNewlines(true) // $ Alert
|
||||
let re2b = try Regex(#"<script.*?>.*?<\/script>"#).ignoresCase(true).dotMatchesNewlines(true)
|
||||
_ = try re2b.firstMatch(in: tainted)
|
||||
// BAD - doesn't match `</script >`
|
||||
let options2c: NSRegularExpression.Options = [.caseInsensitive, .dotMatchesLineSeparators]
|
||||
let ns2c = try NSRegularExpression(pattern: #"<script.*?>.*?<\/script>"#, options: options2c) // $ Alert
|
||||
let ns2c = try NSRegularExpression(pattern: #"<script.*?>.*?<\/script>"#, options: options2c)
|
||||
_ = ns2c.firstMatch(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
|
||||
|
||||
// GOOD
|
||||
@@ -110,71 +110,71 @@ func myRegexpVariantsTests(myUrl: URL) throws {
|
||||
_ = try re5.firstMatch(in: tainted)
|
||||
|
||||
// BAD, does not match newlines
|
||||
let re6 = try Regex(#"<!--.*--!?>"#).ignoresCase(true) // $ Alert
|
||||
let re6 = try Regex(#"<!--.*--!?>"#).ignoresCase(true)
|
||||
_ = try re6.firstMatch(in: tainted)
|
||||
|
||||
// BAD - doesn't match newlines inside the script tag
|
||||
let re7 = try Regex(#"<script.*?>(.|\s)*?<\/script[^>]*>"#).ignoresCase(true) // $ Alert
|
||||
let re7 = try Regex(#"<script.*?>(.|\s)*?<\/script[^>]*>"#).ignoresCase(true)
|
||||
_ = try re7.firstMatch(in: tainted)
|
||||
|
||||
// BAD - doesn't match newlines inside the content
|
||||
let re8 = try Regex(#"<script[^>]*?>.*?<\/script[^>]*>"#).ignoresCase(true) // $ Alert
|
||||
let re8 = try Regex(#"<script[^>]*?>.*?<\/script[^>]*>"#).ignoresCase(true)
|
||||
_ = try re8.firstMatch(in: tainted)
|
||||
|
||||
// BAD - does not match single quotes for attribute values
|
||||
let re9 = try Regex(#"<script(\s|\w|=|")*?>.*?<\/script[^>]*>"#).ignoresCase(true).dotMatchesNewlines(true) // $ Alert
|
||||
let re9 = try Regex(#"<script(\s|\w|=|")*?>.*?<\/script[^>]*>"#).ignoresCase(true).dotMatchesNewlines(true)
|
||||
_ = try re9.firstMatch(in: tainted)
|
||||
|
||||
// BAD - does not match double quotes for attribute values
|
||||
let re10a = try Regex(#"(?is)<script(\s|\w|=|')*?>.*?<\/script[^>]*>"#) // $ Alert
|
||||
let re10a = try Regex(#"(?is)<script(\s|\w|=|')*?>.*?<\/script[^>]*>"#)
|
||||
_ = try re10a.firstMatch(in: tainted)
|
||||
// BAD - does not match double quotes for attribute values
|
||||
let re10b = try Regex(#"<script(\s|\w|=|')*?>.*?<\/script[^>]*>"#).ignoresCase(true).dotMatchesNewlines(true) // $ Alert
|
||||
let re10b = try Regex(#"<script(\s|\w|=|')*?>.*?<\/script[^>]*>"#).ignoresCase(true).dotMatchesNewlines(true)
|
||||
_ = try re10b.firstMatch(in: tainted)
|
||||
// BAD - does not match double quotes for attribute values
|
||||
let options10: NSRegularExpression.Options = [.caseInsensitive, .dotMatchesLineSeparators]
|
||||
let ns10 = try NSRegularExpression(pattern: #"<script(\s|\w|=|')*?>.*?<\/script[^>]*>"#, options: options10) // $ Alert
|
||||
let ns10 = try NSRegularExpression(pattern: #"<script(\s|\w|=|')*?>.*?<\/script[^>]*>"#, options: options10)
|
||||
_ = ns10.firstMatch(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
|
||||
|
||||
// BAD - does not match tabs between attributes
|
||||
let re11a = try Regex(#"(?is)<script( |\n|\w|=|'|")*?>.*?<\/script[^>]*>"#) // $ Alert
|
||||
let re11a = try Regex(#"(?is)<script( |\n|\w|=|'|")*?>.*?<\/script[^>]*>"#)
|
||||
_ = try re11a.firstMatch(in: tainted)
|
||||
// BAD - does not match tabs between attributes
|
||||
let re11b = try Regex(#"<script( |\n|\w|=|'|")*?>.*?<\/script[^>]*>"#).ignoresCase(true).dotMatchesNewlines(true) // $ Alert
|
||||
let re11b = try Regex(#"<script( |\n|\w|=|'|")*?>.*?<\/script[^>]*>"#).ignoresCase(true).dotMatchesNewlines(true)
|
||||
_ = try re11b.firstMatch(in: tainted)
|
||||
// BAD - does not match tabs between attributes
|
||||
let options11: NSRegularExpression.Options = [.caseInsensitive, .dotMatchesLineSeparators]
|
||||
let ns11 = try NSRegularExpression(pattern: #"<script( |\n|\w|=|'|")*?>.*?<\/script[^>]*>"#, options: options11) // $ Alert
|
||||
let ns11 = try NSRegularExpression(pattern: #"<script( |\n|\w|=|'|")*?>.*?<\/script[^>]*>"#, options: options11)
|
||||
_ = ns11.firstMatch(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
|
||||
|
||||
// BAD - does not match uppercase SCRIPT tags
|
||||
let re12a = try Regex(#"(?s)<script.*?>.*?<\/script[^>]*>"#) // $ Alert
|
||||
let re12a = try Regex(#"(?s)<script.*?>.*?<\/script[^>]*>"#)
|
||||
_ = try re12a.firstMatch(in: tainted)
|
||||
// BAD - does not match uppercase SCRIPT tags
|
||||
let re12b = try Regex(#"<script.*?>.*?<\/script[^>]*>"#).dotMatchesNewlines(true) // $ Alert
|
||||
let re12b = try Regex(#"<script.*?>.*?<\/script[^>]*>"#).dotMatchesNewlines(true)
|
||||
_ = try re12b.firstMatch(in: tainted)
|
||||
// BAD - does not match uppercase SCRIPT tags
|
||||
let ns12 = try NSRegularExpression(pattern: #"<script.*?>.*?<\/script[^>]*>"#, options: .dotMatchesLineSeparators) // $ Alert
|
||||
let ns12 = try NSRegularExpression(pattern: #"<script.*?>.*?<\/script[^>]*>"#, options: .dotMatchesLineSeparators)
|
||||
_ = ns12.firstMatch(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
|
||||
|
||||
// BAD - does not match mixed case script tags
|
||||
let re13a = try Regex(#"(?s)<(script|SCRIPT).*?>.*?<\/(script|SCRIPT)[^>]*>"#) // $ Alert
|
||||
let re13a = try Regex(#"(?s)<(script|SCRIPT).*?>.*?<\/(script|SCRIPT)[^>]*>"#)
|
||||
_ = try re13a.firstMatch(in: tainted)
|
||||
// BAD - does not match mixed case script tags
|
||||
let re13b = try Regex(#"<(script|SCRIPT).*?>.*?<\/(script|SCRIPT)[^>]*>"#).dotMatchesNewlines(true) // $ Alert
|
||||
let re13b = try Regex(#"<(script|SCRIPT).*?>.*?<\/(script|SCRIPT)[^>]*>"#).dotMatchesNewlines(true)
|
||||
_ = try re13b.firstMatch(in: tainted)
|
||||
// BAD - does not match mixed case script tags
|
||||
let ns13 = try NSRegularExpression(pattern: #"<(script|SCRIPT).*?>.*?<\/(script|SCRIPT)[^>]*>"#, options: .dotMatchesLineSeparators) // $ Alert
|
||||
let ns13 = try NSRegularExpression(pattern: #"<(script|SCRIPT).*?>.*?<\/(script|SCRIPT)[^>]*>"#, options: .dotMatchesLineSeparators)
|
||||
_ = ns13.firstMatch(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
|
||||
|
||||
// BAD - doesn't match newlines in the end tag
|
||||
let re14a = try Regex(#"(?i)<script[^>]*?>[\s\S]*?<\/script.*>"#) // $ Alert
|
||||
let re14a = try Regex(#"(?i)<script[^>]*?>[\s\S]*?<\/script.*>"#)
|
||||
_ = try re14a.firstMatch(in: tainted)
|
||||
// BAD - doesn't match newlines in the end tag
|
||||
let re14b = try Regex(#"<script[^>]*?>[\s\S]*?<\/script.*>"#).ignoresCase(true) // $ Alert
|
||||
let re14b = try Regex(#"<script[^>]*?>[\s\S]*?<\/script.*>"#).ignoresCase(true)
|
||||
_ = try re14b.firstMatch(in: tainted)
|
||||
// BAD - doesn't match newlines in the end tag
|
||||
let ns14 = try NSRegularExpression(pattern: #"<script[^>]*?>[\s\S]*?<\/script.*>"#, options: .caseInsensitive) // $ Alert
|
||||
let ns14 = try NSRegularExpression(pattern: #"<script[^>]*?>[\s\S]*?<\/script.*>"#, options: .caseInsensitive)
|
||||
_ = ns14.firstMatch(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
|
||||
|
||||
// GOOD
|
||||
@@ -188,33 +188,33 @@ func myRegexpVariantsTests(myUrl: URL) throws {
|
||||
_ = ns15.firstMatch(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
|
||||
|
||||
// BAD - doesn't match comments with the right capture groups
|
||||
let re16 = try Regex(#"<(?:!--([\S|\s]*?)-->)|([^\/\s>]+)[\S\s]*?>"#) // $ Alert
|
||||
let re16 = try Regex(#"<(?:!--([\S|\s]*?)-->)|([^\/\s>]+)[\S\s]*?>"#)
|
||||
_ = try re16.firstMatch(in: tainted)
|
||||
// BAD - doesn't match comments with the right capture groups
|
||||
let ns16 = try NSRegularExpression(pattern: #"<(?:!--([\S|\s]*?)-->)|([^\/\s>]+)[\S\s]*?>"#) // $ Alert
|
||||
let ns16 = try NSRegularExpression(pattern: #"<(?:!--([\S|\s]*?)-->)|([^\/\s>]+)[\S\s]*?>"#)
|
||||
_ = ns16.firstMatch(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
|
||||
|
||||
// BAD - capture groups
|
||||
let re17 = try Regex(#"<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\/\s>]+)((?:\s+[\w\-:.]+(?:\s*=\s*?(?:(?:"[^"]*")|(?:'[^']*')|[^\s"'\/>]+))?)*)[\S\s]*?(\/?)>))"#) // $ Alert
|
||||
let re17 = try Regex(#"<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\/\s>]+)((?:\s+[\w\-:.]+(?:\s*=\s*?(?:(?:"[^"]*")|(?:'[^']*')|[^\s"'\/>]+))?)*)[\S\s]*?(\/?)>))"#)
|
||||
_ = try re17.firstMatch(in: tainted)
|
||||
// BAD - capture groups
|
||||
let ns17 = try NSRegularExpression(pattern: #"<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\/\s>]+)((?:\s+[\w\-:.]+(?:\s*=\s*?(?:(?:"[^"]*")|(?:'[^']*')|[^\s"'\/>]+))?)*)[\S\s]*?(\/?)>))"#, options: .caseInsensitive) // $ Alert
|
||||
let ns17 = try NSRegularExpression(pattern: #"<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\/\s>]+)((?:\s+[\w\-:.]+(?:\s*=\s*?(?:(?:"[^"]*")|(?:'[^']*')|[^\s"'\/>]+))?)*)[\S\s]*?(\/?)>))"#, options: .caseInsensitive)
|
||||
_ = ns17.firstMatch(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
|
||||
|
||||
// BAD - too strict matching on the end tag
|
||||
let ns2_1 = try NSRegularExpression(pattern: #"<script\b[^>]*>([\s\S]*?)<\/script>"#, options: .caseInsensitive) // $ Alert
|
||||
let ns2_1 = try NSRegularExpression(pattern: #"<script\b[^>]*>([\s\S]*?)<\/script>"#, options: .caseInsensitive)
|
||||
_ = ns2_1.matches(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
|
||||
|
||||
// BAD - capture groups
|
||||
let ns2_2 = try NSRegularExpression(pattern: #"(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|<!(--.*?--\s*)+>)"#, options: .caseInsensitive) // $ Alert
|
||||
let ns2_2 = try NSRegularExpression(pattern: #"(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|<!(--.*?--\s*)+>)"#, options: .caseInsensitive)
|
||||
_ = ns2_2.matches(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
|
||||
|
||||
// BAD - capture groups
|
||||
let ns2_3 = try NSRegularExpression(pattern: #"<(?:(?:!--([\w\W]*?)-->)|(?:!\[CDATA\[([\w\W]*?)\]\]>)|(?:!DOCTYPE([\w\W]*?)>)|(?:\?([^\s\/<>]+) ?([\w\W]*?)[?/]>)|(?:\/([A-Za-z][A-Za-z0-9\-_\:\.]*)>)|(?:([A-Za-z][A-Za-z0-9\-_\:\.]*)((?:\s+[^"'>]+(?:(?:"[^"]*")|(?:'[^']*')|[^>]*))*|\/|\s+)>))"#) // $ Alert
|
||||
let ns2_3 = try NSRegularExpression(pattern: #"<(?:(?:!--([\w\W]*?)-->)|(?:!\[CDATA\[([\w\W]*?)\]\]>)|(?:!DOCTYPE([\w\W]*?)>)|(?:\?([^\s\/<>]+) ?([\w\W]*?)[?/]>)|(?:\/([A-Za-z][A-Za-z0-9\-_\:\.]*)>)|(?:([A-Za-z][A-Za-z0-9\-_\:\.]*)((?:\s+[^"'>]+(?:(?:"[^"]*")|(?:'[^']*')|[^>]*))*|\/|\s+)>))"#)
|
||||
_ = ns2_3.matches(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
|
||||
|
||||
// BAD - capture groups
|
||||
let ns2_4 = try NSRegularExpression(pattern: #"<!--([\w\W]*?)-->|<([^>]*?)>"#) // $ Alert
|
||||
let ns2_4 = try NSRegularExpression(pattern: #"<!--([\w\W]*?)-->|<([^>]*?)>"#)
|
||||
_ = ns2_4.matches(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
|
||||
|
||||
// GOOD - it's used with the ignorecase flag
|
||||
@@ -222,7 +222,7 @@ func myRegexpVariantsTests(myUrl: URL) throws {
|
||||
_ = ns2_5.matches(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
|
||||
|
||||
// BAD - doesn't match --!>
|
||||
let ns2_6 = try NSRegularExpression(pattern: #"-->"#) // $ Alert
|
||||
let ns2_6 = try NSRegularExpression(pattern: #"-->"#)
|
||||
_ = ns2_6.matches(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
|
||||
|
||||
// GOOD
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
query: queries/Security/CWE-1204/StaticInitializationVector.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
queries/Security/CWE-1204/StaticInitializationVector.ql
|
||||
|
||||
@@ -57,28 +57,28 @@ func test(myPassword: String) {
|
||||
let myKeyDerivationSettings = RNCryptorKeyDerivationSettings()
|
||||
let myHandler = {}
|
||||
let myRandomIV = Data(getRandomArray())
|
||||
let myConstIV1 = Data(0) // $ Source
|
||||
let myConstIV2 = Data(123) // $ Source
|
||||
let myConstIV3 = Data([1,2,3,4,5]) // $ Source
|
||||
let myConstIV4 = Data("iv") // $ Source
|
||||
let myConstIV1 = Data(0)
|
||||
let myConstIV2 = Data(123)
|
||||
let myConstIV3 = Data([1,2,3,4,5])
|
||||
let myConstIV4 = Data("iv")
|
||||
let mySalt = Data(0)
|
||||
let mySalt2 = Data(0)
|
||||
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, encryptionKey: myKey, hmacKey: myHMACKey, iv: myRandomIV, handler: myHandler) // GOOD
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, encryptionKey: myKey, hmacKey: myHMACKey, iv: myConstIV1, handler: myHandler) // $ Alert
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, encryptionKey: myKey, hmacKey: myHMACKey, iv: myConstIV1, handler: myHandler) // BAD
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, encryptionKey: myKey, HMACKey: myHMACKey, IV: myRandomIV, handler: myHandler) // GOOD
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, encryptionKey: myKey, HMACKey: myHMACKey, IV: myConstIV2, handler: myHandler) // $ Alert
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, encryptionKey: myKey, HMACKey: myHMACKey, IV: myConstIV2, handler: myHandler) // BAD
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, iv: myRandomIV, encryptionSalt: mySalt, hmacSalt: mySalt2, handler: myHandler) // GOOD
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, iv: myConstIV3, encryptionSalt: mySalt, hmacSalt: mySalt2, handler: myHandler) // $ Alert
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, iv: myConstIV3, encryptionSalt: mySalt, hmacSalt: mySalt2, handler: myHandler) // BAD
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, IV: myRandomIV, encryptionSalt: mySalt, HMACSalt: mySalt2, handler: myHandler) // GOOD
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, IV: myConstIV4, encryptionSalt: mySalt, HMACSalt: mySalt2, handler: myHandler) // $ Alert
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, IV: myConstIV4, encryptionSalt: mySalt, HMACSalt: mySalt2, handler: myHandler) // BAD
|
||||
|
||||
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, encryptionKey: myKey, hmacKey: myHMACKey, iv: myRandomIV) // GOOD
|
||||
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, encryptionKey: myKey, hmacKey: myHMACKey, iv: myConstIV1) // $ Alert
|
||||
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, encryptionKey: myKey, hmacKey: myHMACKey, iv: myConstIV1) // BAD
|
||||
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, encryptionKey: myKey, HMACKey: myHMACKey, IV: myRandomIV) // GOOD
|
||||
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, encryptionKey: myKey, HMACKey: myHMACKey, IV: myConstIV2) // $ Alert
|
||||
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, encryptionKey: myKey, HMACKey: myHMACKey, IV: myConstIV2) // BAD
|
||||
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myPassword, iv: myRandomIV, encryptionSalt: mySalt, hmacSalt: mySalt2) // GOOD
|
||||
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myPassword, iv: myConstIV3, encryptionSalt: mySalt, hmacSalt: mySalt2) // $ Alert
|
||||
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myPassword, iv: myConstIV3, encryptionSalt: mySalt, hmacSalt: mySalt2) // BAD
|
||||
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, password: myPassword, IV: myRandomIV, encryptionSalt: mySalt, HMACSalt: mySalt2) // GOOD
|
||||
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, password: myPassword, IV: myConstIV4, encryptionSalt: mySalt, HMACSalt: mySalt2) // $ Alert
|
||||
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, password: myPassword, IV: myConstIV4, encryptionSalt: mySalt, HMACSalt: mySalt2) // BAD
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ final class GCM: BlockMode {
|
||||
enum Mode { case combined, detached }
|
||||
init(iv: Array<UInt8>, additionalAuthenticatedData: Array<UInt8>? = nil, tagLength: Int = 16, mode: Mode = .detached) { }
|
||||
convenience init(iv: Array<UInt8>, authenticationTag: Array<UInt8>, additionalAuthenticatedData: Array<UInt8>? = nil, mode: Mode = .detached) {
|
||||
self.init(iv: iv, additionalAuthenticatedData: additionalAuthenticatedData, tagLength: authenticationTag.count, mode: mode) // $ Alert
|
||||
self.init(iv: iv, additionalAuthenticatedData: additionalAuthenticatedData, tagLength: authenticationTag.count, mode: mode)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ enum Padding: PaddingProtocol {
|
||||
|
||||
// Helper functions
|
||||
func getConstantString() -> String {
|
||||
"this string is constant" // $ Source
|
||||
"this string is constant"
|
||||
}
|
||||
|
||||
func getConstantArray() -> Array<UInt8> {
|
||||
@@ -96,7 +96,7 @@ func getRandomArray() -> Array<UInt8> {
|
||||
// --- tests ---
|
||||
|
||||
func test() {
|
||||
let iv: Array<UInt8> = [0x2a, 0x3a, 0x80, 0x05, 0xaf, 0x46, 0x58, 0x2d, 0x66, 0x52, 0x10, 0xae, 0x86, 0xd3, 0x8e, 0x8f] // $ Source
|
||||
let iv: Array<UInt8> = [0x2a, 0x3a, 0x80, 0x05, 0xaf, 0x46, 0x58, 0x2d, 0x66, 0x52, 0x10, 0xae, 0x86, 0xd3, 0x8e, 0x8f]
|
||||
let iv2 = getConstantArray()
|
||||
let ivString = getConstantString()
|
||||
|
||||
@@ -109,63 +109,63 @@ func test() {
|
||||
let keyString = String(cString: key)
|
||||
|
||||
// AES test cases
|
||||
let ab1 = AES(key: keyString, iv: ivString) // $ Alert
|
||||
let ab2 = AES(key: keyString, iv: ivString, padding: padding) // $ Alert
|
||||
let ab1 = AES(key: keyString, iv: ivString) // BAD
|
||||
let ab2 = AES(key: keyString, iv: ivString, padding: padding) // BAD
|
||||
let ag1 = AES(key: keyString, iv: randomIvString) // GOOD
|
||||
let ag2 = AES(key: keyString, iv: randomIvString, padding: padding) // GOOD
|
||||
|
||||
// ChaCha20 test cases
|
||||
let cb1 = ChaCha20(key: keyString, iv: ivString) // $ Alert
|
||||
let cb1 = ChaCha20(key: keyString, iv: ivString) // BAD
|
||||
let cg1 = ChaCha20(key: keyString, iv: randomIvString) // GOOD
|
||||
|
||||
// Blowfish test cases
|
||||
let bb1 = Blowfish(key: keyString, iv: ivString) // $ Alert
|
||||
let bb2 = Blowfish(key: keyString, iv: ivString, padding: padding) // $ Alert
|
||||
let bb1 = Blowfish(key: keyString, iv: ivString) // BAD
|
||||
let bb2 = Blowfish(key: keyString, iv: ivString, padding: padding) // BAD
|
||||
let bg1 = Blowfish(key: keyString, iv: randomIvString) // GOOD
|
||||
let bg2 = Blowfish(key: keyString, iv: randomIvString, padding: padding) // GOOD
|
||||
|
||||
// Rabbit
|
||||
let rb1 = Rabbit(key: key, iv: iv) // $ Alert
|
||||
let rb2 = Rabbit(key: key, iv: iv2) // $ Alert
|
||||
let rb3 = Rabbit(key: keyString, iv: ivString) // $ Alert
|
||||
let rb1 = Rabbit(key: key, iv: iv) // BAD
|
||||
let rb2 = Rabbit(key: key, iv: iv2) // BAD
|
||||
let rb3 = Rabbit(key: keyString, iv: ivString) // BAD
|
||||
let rg1 = Rabbit(key: key, iv: randomIv) // GOOD
|
||||
let rg2 = Rabbit(key: keyString, iv: randomIvString) // GOOD
|
||||
|
||||
// CBC
|
||||
let cbcb1 = CBC(iv: iv) // $ Alert
|
||||
let cbcb1 = CBC(iv: iv) // BAD
|
||||
let cbcg1 = CBC(iv: randomIv) // GOOD
|
||||
|
||||
// CFB
|
||||
let cfbb1 = CFB(iv: iv) // $ Alert
|
||||
let cfbb2 = CFB(iv: iv, segmentSize: CFB.SegmentSize.cfb8) // $ Alert
|
||||
let cfbb1 = CFB(iv: iv) // BAD
|
||||
let cfbb2 = CFB(iv: iv, segmentSize: CFB.SegmentSize.cfb8) // BAD
|
||||
let cfbg1 = CFB(iv: randomIv) // GOOD
|
||||
let cfbg2 = CFB(iv: randomIv, segmentSize: CFB.SegmentSize.cfb8) // GOOD
|
||||
|
||||
// GCM
|
||||
let cgmb1 = GCM(iv: iv) // $ Alert
|
||||
let cgmb2 = GCM(iv: iv, additionalAuthenticatedData: randomArray, tagLength: 8, mode: GCM.Mode.combined) // $ Alert
|
||||
let cgmb3 = GCM(iv: iv, authenticationTag: randomArray, additionalAuthenticatedData: randomArray, mode: GCM.Mode.combined) // $ Alert
|
||||
let cgmb1 = GCM(iv: iv) // BAD
|
||||
let cgmb2 = GCM(iv: iv, additionalAuthenticatedData: randomArray, tagLength: 8, mode: GCM.Mode.combined) // BAD
|
||||
let cgmb3 = GCM(iv: iv, authenticationTag: randomArray, additionalAuthenticatedData: randomArray, mode: GCM.Mode.combined) // BAD
|
||||
let cgmg1 = GCM(iv: randomIv) // GOOD
|
||||
let cgmg2 = GCM(iv: randomIv, additionalAuthenticatedData: randomArray, tagLength: 8, mode: GCM.Mode.combined) // GOOD
|
||||
let cgmg3 = GCM(iv: randomIv, authenticationTag: randomArray, additionalAuthenticatedData: randomArray, mode: GCM.Mode.combined) // GOOD
|
||||
|
||||
// OFB
|
||||
let ofbb1 = OFB(iv: iv) // $ Alert
|
||||
let ofbb1 = OFB(iv: iv) // BAD
|
||||
let ofbg1 = OFB(iv: randomIv) // GOOD
|
||||
|
||||
// PCBC
|
||||
let pcbcb1 = PCBC(iv: iv) // $ Alert
|
||||
let pcbcb1 = PCBC(iv: iv) // BAD
|
||||
let pcbcg1 = PCBC(iv: randomIv) // GOOD
|
||||
|
||||
// CCM
|
||||
let ccmb1 = CCM(iv: iv, tagLength: 0, messageLength: 0, additionalAuthenticatedData: randomArray) // $ Alert
|
||||
let ccmb2 = CCM(iv: iv, tagLength: 0, messageLength: 0, authenticationTag: randomArray, additionalAuthenticatedData: randomArray) // $ Alert
|
||||
let ccmb1 = CCM(iv: iv, tagLength: 0, messageLength: 0, additionalAuthenticatedData: randomArray) // BAD
|
||||
let ccmb2 = CCM(iv: iv, tagLength: 0, messageLength: 0, authenticationTag: randomArray, additionalAuthenticatedData: randomArray) // BAD
|
||||
let ccmg1 = CCM(iv: randomIv, tagLength: 0, messageLength: 0, additionalAuthenticatedData: randomArray) // GOOD
|
||||
let ccmg2 = CCM(iv: randomIv, tagLength: 0, messageLength: 0, authenticationTag: randomArray, additionalAuthenticatedData: randomArray) // GOOD
|
||||
|
||||
// CTR
|
||||
let ctrb1 = CTR(iv: iv) // $ Alert
|
||||
let ctrb2 = CTR(iv: iv, counter: 0) // $ Alert
|
||||
let ctrb1 = CTR(iv: iv) // BAD
|
||||
let ctrb2 = CTR(iv: iv, counter: 0) // BAD
|
||||
let ctrg1 = CTR(iv: randomIv) // GOOD
|
||||
let ctrg2 = CTR(iv: randomIv, counter: 0) // GOOD
|
||||
}
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
query: queries/Security/CWE-1333/ReDoS.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
queries/Security/CWE-1333/ReDoS.ql
|
||||
@@ -61,25 +61,25 @@ func myRegexpTests(myUrl: URL) throws {
|
||||
// Regex
|
||||
|
||||
_ = "((a*)*b)" // GOOD (never used)
|
||||
_ = try Regex("((a*)*b)") // $ Alert // DUBIOUS (never used) [FLAGGED]
|
||||
_ = try Regex("((a*)*b)").firstMatch(in: untainted) // $ Alert // DUBIOUS (never used on tainted input) [FLAGGED]
|
||||
_ = try Regex("((a*)*b)").firstMatch(in: tainted) // $ Alert
|
||||
_ = try Regex("((a*)*b)") // DUBIOUS (never used) [FLAGGED]
|
||||
_ = try Regex("((a*)*b)").firstMatch(in: untainted) // DUBIOUS (never used on tainted input) [FLAGGED]
|
||||
_ = try Regex("((a*)*b)").firstMatch(in: tainted) // BAD
|
||||
_ = try Regex(".*").firstMatch(in: tainted) // GOOD (safe regex)
|
||||
|
||||
let str = "((a*)*b)" // $ Alert
|
||||
let str = "((a*)*b)" // BAD
|
||||
let regex = try Regex(str)
|
||||
_ = try regex.firstMatch(in: tainted)
|
||||
|
||||
_ = try Regex(#"(?is)X(?:.|\n)*Y"#) // $ Alert // BAD - suggested attack should begin with 'x' or 'X', *not* 'isx' or 'isX'
|
||||
_ = try Regex(#"(?is)X(?:.|\n)*Y"#) // BAD - suggested attack should begin with 'x' or 'X', *not* 'isx' or 'isX'
|
||||
|
||||
// NSRegularExpression
|
||||
|
||||
_ = try? NSRegularExpression(pattern: "((a*)*b)") // $ Alert // DUBIOUS (never used) [FLAGGED]
|
||||
_ = try? NSRegularExpression(pattern: "((a*)*b)") // DUBIOUS (never used) [FLAGGED]
|
||||
|
||||
let nsregex1 = try? NSRegularExpression(pattern: "((a*)*b)") // $ Alert // DUBIOUS (never used on tainted input) [FLAGGED]
|
||||
let nsregex1 = try? NSRegularExpression(pattern: "((a*)*b)") // DUBIOUS (never used on tainted input) [FLAGGED]
|
||||
_ = nsregex1?.stringByReplacingMatches(in: untainted, range: NSRange(location: 0, length: untainted.utf16.count), withTemplate: "")
|
||||
|
||||
let nsregex2 = try? NSRegularExpression(pattern: "((a*)*b)") // $ Alert
|
||||
let nsregex2 = try? NSRegularExpression(pattern: "((a*)*b)") // BAD
|
||||
_ = nsregex2?.stringByReplacingMatches(in: tainted, range: NSRange(location: 0, length: tainted.utf16.count), withTemplate: "")
|
||||
|
||||
let nsregex3 = try? NSRegularExpression(pattern: ".*") // GOOD (safe regex)
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
query: queries/Security/CWE-134/UncontrolledFormatString.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
queries/Security/CWE-134/UncontrolledFormatString.ql
|
||||
@@ -76,7 +76,7 @@ func vasprintf_l(_ ret: UnsafeMutablePointer<UnsafeMutablePointer<CChar>?>?, _ l
|
||||
|
||||
func MyLog(_ format: String, _ args: CVarArg...) {
|
||||
withVaList(args) { arglist in
|
||||
NSLogv(format, arglist) // $ Alert
|
||||
NSLogv(format, arglist) // BAD
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,34 +88,34 @@ class MyString {
|
||||
}
|
||||
|
||||
func tests() throws {
|
||||
let tainted = try! String(contentsOf: URL(string: "http://example.com")!) // $ Source
|
||||
let tainted = try! String(contentsOf: URL(string: "http://example.com")!)
|
||||
|
||||
_ = String("abc") // GOOD: not a format string
|
||||
_ = String(tainted) // GOOD: not a format string
|
||||
|
||||
_ = String(format: "abc") // GOOD: not tainted
|
||||
_ = String(format: tainted) // $ Alert
|
||||
_ = String(format: tainted) // BAD
|
||||
_ = String(format: "%s", "abc") // GOOD: not tainted
|
||||
_ = String(format: "%s", tainted) // GOOD: format string itself is not tainted
|
||||
_ = String(format: tainted, "abc") // $ Alert
|
||||
_ = String(format: tainted, tainted) // $ Alert
|
||||
_ = String(format: tainted, "abc") // BAD
|
||||
_ = String(format: tainted, tainted) // BAD
|
||||
|
||||
_ = String(format: tainted, arguments: []) // $ Alert
|
||||
_ = String(format: tainted, locale: nil) // $ Alert
|
||||
_ = String(format: tainted, locale: nil, arguments: []) // $ Alert
|
||||
_ = String.localizedStringWithFormat(tainted) // $ Alert
|
||||
_ = String(format: tainted, arguments: []) // BAD
|
||||
_ = String(format: tainted, locale: nil) // BAD
|
||||
_ = String(format: tainted, locale: nil, arguments: []) // BAD
|
||||
_ = String.localizedStringWithFormat(tainted) // BAD
|
||||
|
||||
_ = NSString(format: NSString(string: tainted), "abc") // $ Alert
|
||||
NSString.localizedStringWithFormat(NSString(string: tainted)) // $ Alert
|
||||
_ = NSString(format: NSString(string: tainted), "abc") // BAD
|
||||
NSString.localizedStringWithFormat(NSString(string: tainted)) // BAD
|
||||
|
||||
_ = NSMutableString(format: NSString(string: tainted), "abc") // $ Alert
|
||||
NSMutableString.localizedStringWithFormat(NSString(string: tainted)) // $ Alert
|
||||
_ = NSMutableString(format: NSString(string: tainted), "abc") // BAD
|
||||
NSMutableString.localizedStringWithFormat(NSString(string: tainted)) // BAD
|
||||
|
||||
NSLog("abc") // GOOD: not tainted
|
||||
NSLog(tainted) // $ Alert
|
||||
MyLog(tainted) // $ Alert
|
||||
NSLog(tainted) // BAD
|
||||
MyLog(tainted) // BAD
|
||||
|
||||
NSException.raise(NSExceptionName("exception"), format: tainted, arguments: getVaList([])) // $ Alert
|
||||
NSException.raise(NSExceptionName("exception"), format: tainted, arguments: getVaList([])) // BAD
|
||||
|
||||
let taintedVal = Int(tainted)!
|
||||
let taintedSan = "\(taintedVal)"
|
||||
@@ -127,32 +127,32 @@ func tests() throws {
|
||||
|
||||
_ = String("abc").appendingFormat("%s", "abc") // GOOD: not tainted
|
||||
_ = String("abc").appendingFormat("%s", tainted) // GOOD: format not tainted
|
||||
_ = String("abc").appendingFormat(tainted, "abc") // $ Alert
|
||||
_ = String("abc").appendingFormat(tainted, "abc") // BAD
|
||||
_ = String(tainted).appendingFormat("%s", "abc") // GOOD: format not tainted
|
||||
|
||||
let s = NSMutableString(string: "foo")
|
||||
s.appendFormat(NSString(string: "%s"), "abc") // GOOD: not tainted
|
||||
s.appendFormat(NSString(string: tainted), "abc") // $ Alert
|
||||
s.appendFormat(NSString(string: tainted), "abc") // BAD
|
||||
|
||||
_ = NSPredicate(format: tainted) // GOOD: this should be flagged by `swift/predicate-injection`, not `swift/uncontrolled-format-string`
|
||||
|
||||
tainted.withCString({
|
||||
cstr in
|
||||
_ = dprintf(0, cstr, "abc") // $ Alert
|
||||
_ = dprintf(0, cstr, "abc") // BAD
|
||||
_ = dprintf(0, "%s", cstr) // GOOD: format not tainted
|
||||
_ = vprintf(cstr, getVaList(["abc"])) // $ Alert
|
||||
_ = vprintf(cstr, getVaList(["abc"])) // BAD
|
||||
_ = vprintf("%s", getVaList([cstr])) // GOOD: format not tainted
|
||||
_ = vfprintf(nil, cstr, getVaList(["abc"])) // $ Alert
|
||||
_ = vfprintf(nil, cstr, getVaList(["abc"])) // BAD
|
||||
_ = vfprintf(nil, "%s", getVaList([cstr])) // GOOD: format not tainted
|
||||
_ = vasprintf_l(nil, nil, cstr, getVaList(["abc"])) // $ Alert
|
||||
_ = vasprintf_l(nil, nil, cstr, getVaList(["abc"])) // BAD
|
||||
_ = vasprintf_l(nil, nil, "%s", getVaList([cstr])) // GOOD: format not tainted
|
||||
})
|
||||
|
||||
myFormatMessage(string: tainted, "abc") // BAD [NOT DETECTED]
|
||||
myFormatMessage(string: "%s", tainted) // GOOD: format not tainted
|
||||
|
||||
_ = MyString(format: tainted, "abc") // $ Alert
|
||||
_ = MyString(format: tainted, "abc") // BAD
|
||||
_ = MyString(format: "%s", tainted) // GOOD: format not tainted
|
||||
_ = MyString(formatString: tainted, "abc") // $ Alert
|
||||
_ = MyString(formatString: tainted, "abc") // BAD
|
||||
_ = MyString(formatString: "%s", tainted) // GOOD: format not tainted
|
||||
}
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
query: queries/Security/CWE-259/ConstantPassword.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
queries/Security/CWE-259/ConstantPassword.ql
|
||||
|
||||
@@ -66,7 +66,7 @@ func test(cond: Bool) {
|
||||
let myData = Data(0)
|
||||
|
||||
let myRandomPassword = getARandomPassword()
|
||||
let myConstPassword = "abc123" // $ Source
|
||||
let myConstPassword = "abc123"
|
||||
let myMaybePassword = cond ? myRandomPassword : myConstPassword
|
||||
|
||||
// reasonable usage
|
||||
@@ -74,11 +74,11 @@ func test(cond: Bool) {
|
||||
let a = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myRandomPassword) // GOOD
|
||||
let _ = try? myDecryptor.decryptData(a, withPassword: myRandomPassword) // GOOD
|
||||
|
||||
let b = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myConstPassword) // $ Alert
|
||||
let _ = try? myDecryptor.decryptData(b, withPassword: myConstPassword) // $ Alert
|
||||
let b = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myConstPassword) // BAD
|
||||
let _ = try? myDecryptor.decryptData(b, withPassword: myConstPassword) // BAD
|
||||
|
||||
let c = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myMaybePassword) // $ Alert
|
||||
let _ = try? myDecryptor.decryptData(c, withPassword: myMaybePassword) // $ Alert
|
||||
let c = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myMaybePassword) // BAD
|
||||
let _ = try? myDecryptor.decryptData(c, withPassword: myMaybePassword) // BAD
|
||||
|
||||
// all methods
|
||||
|
||||
@@ -88,22 +88,22 @@ func test(cond: Bool) {
|
||||
let mySalt = Data(0)
|
||||
let mySalt2 = Data(0)
|
||||
|
||||
let _ = myEncryptor.key(forPassword: myConstPassword, salt: mySalt, settings: myKeyDerivationSettings) // $ Alert
|
||||
let _ = myEncryptor.keyForPassword(myConstPassword, salt: mySalt, settings: myKeyDerivationSettings) // $ Alert
|
||||
let _ = myDecryptor.key(forPassword: myConstPassword, salt: mySalt, settings: myKeyDerivationSettings) // $ Alert
|
||||
let _ = myDecryptor.keyForPassword(myConstPassword, salt: mySalt, settings: myKeyDerivationSettings) // $ Alert
|
||||
let _ = myEncryptor.key(forPassword: myConstPassword, salt: mySalt, settings: myKeyDerivationSettings) // BAD
|
||||
let _ = myEncryptor.keyForPassword(myConstPassword, salt: mySalt, settings: myKeyDerivationSettings) // BAD
|
||||
let _ = myDecryptor.key(forPassword: myConstPassword, salt: mySalt, settings: myKeyDerivationSettings) // BAD
|
||||
let _ = myDecryptor.keyForPassword(myConstPassword, salt: mySalt, settings: myKeyDerivationSettings) // BAD
|
||||
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myConstPassword, handler: myHandler) // $ Alert
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myConstPassword, iv: myIV, encryptionSalt: mySalt, hmacSalt: mySalt2, handler: myHandler) // $ Alert
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myConstPassword, IV: myIV, encryptionSalt: mySalt, HMACSalt: mySalt2, handler: myHandler) // $ Alert
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myConstPassword, handler: myHandler) // BAD
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myConstPassword, iv: myIV, encryptionSalt: mySalt, hmacSalt: mySalt2, handler: myHandler) // BAD
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myConstPassword, IV: myIV, encryptionSalt: mySalt, HMACSalt: mySalt2, handler: myHandler) // BAD
|
||||
|
||||
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myConstPassword) // $ Alert
|
||||
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, password: myConstPassword) // $ Alert
|
||||
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myConstPassword, iv: myIV, encryptionSalt: mySalt, hmacSalt: mySalt2) // $ Alert
|
||||
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, password: myConstPassword, IV: myIV, encryptionSalt: mySalt, HMACSalt: mySalt2) // $ Alert
|
||||
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myConstPassword) // BAD
|
||||
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, password: myConstPassword) // BAD
|
||||
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myConstPassword, iv: myIV, encryptionSalt: mySalt, hmacSalt: mySalt2) // BAD
|
||||
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, password: myConstPassword, IV: myIV, encryptionSalt: mySalt, HMACSalt: mySalt2) // BAD
|
||||
|
||||
let _ = RNDecryptor(password: myConstPassword, handler: myHandler) // $ Alert
|
||||
let _ = RNDecryptor(password: myConstPassword, handler: myHandler) // BAD
|
||||
|
||||
let _ = try? myDecryptor.decryptData(myData, withPassword: myConstPassword) // $ Alert
|
||||
let _ = try? myDecryptor.decryptData(myData, withSettings: kRNCryptorAES256Settings, password: myConstPassword) // $ Alert
|
||||
let _ = try? myDecryptor.decryptData(myData, withPassword: myConstPassword) // BAD
|
||||
let _ = try? myDecryptor.decryptData(myData, withSettings: kRNCryptorAES256Settings, password: myConstPassword) // BAD
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ final class Scrypt {
|
||||
|
||||
// Helper functions
|
||||
func getConstantString() -> String {
|
||||
"this string is constant" // $ Source
|
||||
"this string is constant"
|
||||
}
|
||||
|
||||
func getConstantArray() -> Array<UInt8> {
|
||||
@@ -40,7 +40,7 @@ func getRandomArray() -> Array<UInt8> {
|
||||
// --- tests ---
|
||||
|
||||
func test() {
|
||||
let constantPassword: Array<UInt8> = [0x2a, 0x3a, 0x80, 0x05, 0xaf, 0x46, 0x58, 0x2d, 0x66, 0x52, 0x10, 0xae, 0x86, 0xd3, 0x8e, 0x8f] // $ Source
|
||||
let constantPassword: Array<UInt8> = [0x2a, 0x3a, 0x80, 0x05, 0xaf, 0x46, 0x58, 0x2d, 0x66, 0x52, 0x10, 0xae, 0x86, 0xd3, 0x8e, 0x8f]
|
||||
let constantStringPassword = getConstantArray()
|
||||
let randomPassword = getRandomArray()
|
||||
let randomArray = getRandomArray()
|
||||
@@ -48,23 +48,23 @@ func test() {
|
||||
let iterations = 120120
|
||||
|
||||
// HKDF test cases
|
||||
let hkdfb1 = HKDF(password: constantPassword, salt: randomArray, info: randomArray, keyLength: 0, variant: variant) // $ Alert
|
||||
let hkdfb2 = HKDF(password: constantStringPassword, salt: randomArray, info: randomArray, keyLength: 0, variant: variant) // $ Alert
|
||||
let hkdfb1 = HKDF(password: constantPassword, salt: randomArray, info: randomArray, keyLength: 0, variant: variant) // BAD
|
||||
let hkdfb2 = HKDF(password: constantStringPassword, salt: randomArray, info: randomArray, keyLength: 0, variant: variant) // BAD
|
||||
let hkdfg1 = HKDF(password: randomPassword, salt: randomArray, info: randomArray, keyLength: 0, variant: variant) // GOOD
|
||||
|
||||
// PBKDF1 test cases
|
||||
let pbkdf1b1 = PKCS5.PBKDF1(password: constantPassword, salt: randomArray, iterations: iterations, keyLength: 0) // $ Alert
|
||||
let pbkdf1b2 = PKCS5.PBKDF1(password: constantStringPassword, salt: randomArray, iterations: iterations, keyLength: 0) // $ Alert
|
||||
let pbkdf1b1 = PKCS5.PBKDF1(password: constantPassword, salt: randomArray, iterations: iterations, keyLength: 0) // BAD
|
||||
let pbkdf1b2 = PKCS5.PBKDF1(password: constantStringPassword, salt: randomArray, iterations: iterations, keyLength: 0) // BAD
|
||||
let pbkdf1g1 = PKCS5.PBKDF1(password: randomPassword, salt: randomArray, iterations: iterations, keyLength: 0) // GOOD
|
||||
|
||||
|
||||
// PBKDF2 test cases
|
||||
let pbkdf2b1 = PKCS5.PBKDF2(password: constantPassword, salt: randomArray, iterations: iterations, keyLength: 0) // $ Alert
|
||||
let pbkdf2b2 = PKCS5.PBKDF2(password: constantStringPassword, salt: randomArray, iterations: iterations, keyLength: 0) // $ Alert
|
||||
let pbkdf2b1 = PKCS5.PBKDF2(password: constantPassword, salt: randomArray, iterations: iterations, keyLength: 0) // BAD
|
||||
let pbkdf2b2 = PKCS5.PBKDF2(password: constantStringPassword, salt: randomArray, iterations: iterations, keyLength: 0) // BAD
|
||||
let pbkdf2g1 = PKCS5.PBKDF2(password: randomPassword, salt: randomArray, iterations: iterations, keyLength: 0) // GOOD
|
||||
|
||||
// Scrypt test cases
|
||||
let scryptb1 = Scrypt(password: constantPassword, salt: randomArray, dkLen: 64, N: 16384, r: 8, p: 1) // $ Alert
|
||||
let scryptb2 = Scrypt(password: constantStringPassword, salt: randomArray, dkLen: 64, N: 16384, r: 8, p: 1) // $ Alert
|
||||
let scryptb1 = Scrypt(password: constantPassword, salt: randomArray, dkLen: 64, N: 16384, r: 8, p: 1) // BAD
|
||||
let scryptb2 = Scrypt(password: constantStringPassword, salt: randomArray, dkLen: 64, N: 16384, r: 8, p: 1) // BAD
|
||||
let scryptg1 = Scrypt(password: randomPassword, salt: randomArray, dkLen: 64, N: 16384, r: 8, p: 1) // GOOD
|
||||
}
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
query: queries/Security/CWE-311/CleartextStorageDatabase.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
queries/Security/CWE-311/CleartextStorageDatabase.ql
|
||||
@@ -1,2 +1 @@
|
||||
query: queries/Security/CWE-311/CleartextTransmission.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
queries/Security/CWE-311/CleartextTransmission.ql
|
||||
@@ -116,64 +116,64 @@ func ==<V>(lhs: Expression<V>, rhs: V) -> Expression<Bool> { return Expression<B
|
||||
func test_sqlite_swift_api(db: Connection, id: Int, mobilePhoneNumber: String) throws {
|
||||
// --- sensitive data in SQL (in practice these cases may also be SQL injection) ---
|
||||
|
||||
let insertQuery = "INSERT INTO CONTACTS(ID, NUMBER) VALUES(\(id), \(mobilePhoneNumber));" // $ Source
|
||||
let updateQuery = "UPDATE CONTACTS SET NUMBER=\(mobilePhoneNumber) WHERE ID=\(id);" // $ Source
|
||||
let insertQuery = "INSERT INTO CONTACTS(ID, NUMBER) VALUES(\(id), \(mobilePhoneNumber));"
|
||||
let updateQuery = "UPDATE CONTACTS SET NUMBER=\(mobilePhoneNumber) WHERE ID=\(id);"
|
||||
let deleteQuery = "DELETE FROM CONTACTS WHERE ID=\(id);"
|
||||
|
||||
try db.execute(insertQuery) // $ Alert // BAD (sensitive data)
|
||||
try db.execute(updateQuery) // $ Alert // BAD (sensitive data)
|
||||
try db.execute(insertQuery) // BAD (sensitive data)
|
||||
try db.execute(updateQuery) // BAD (sensitive data)
|
||||
try db.execute(deleteQuery) // GOOD
|
||||
|
||||
_ = try db.prepare(insertQuery).run() // $ Alert // BAD (sensitive data)
|
||||
_ = try db.prepare(updateQuery).run() // $ Alert // BAD (sensitive data)
|
||||
_ = try db.prepare(insertQuery).run() // BAD (sensitive data)
|
||||
_ = try db.prepare(updateQuery).run() // BAD (sensitive data)
|
||||
_ = try db.prepare(deleteQuery).run() // GOOD
|
||||
|
||||
_ = try db.run(insertQuery) // $ Alert // BAD (sensitive data)
|
||||
_ = try db.run(updateQuery) // $ Alert // BAD (sensitive data)
|
||||
_ = try db.run(insertQuery) // BAD (sensitive data)
|
||||
_ = try db.run(updateQuery) // BAD (sensitive data)
|
||||
_ = try db.run(deleteQuery) // GOOD
|
||||
|
||||
_ = try db.scalar(insertQuery) // $ Alert // BAD (sensitive data)
|
||||
_ = try db.scalar(updateQuery) // $ Alert // BAD (sensitive data)
|
||||
_ = try db.scalar(insertQuery) // BAD (sensitive data)
|
||||
_ = try db.scalar(updateQuery) // BAD (sensitive data)
|
||||
_ = try db.scalar(deleteQuery) // GOOD
|
||||
|
||||
_ = try Statement(db, insertQuery).run() // $ Alert // BAD (sensitive data)
|
||||
_ = try Statement(db, updateQuery).run() // $ Alert // BAD (sensitive data)
|
||||
_ = try Statement(db, insertQuery).run() // BAD (sensitive data)
|
||||
_ = try Statement(db, updateQuery).run() // BAD (sensitive data)
|
||||
_ = try Statement(db, deleteQuery).run() // GOOD
|
||||
|
||||
// --- sensitive data in bindings ---
|
||||
|
||||
let varQuery1 = "UPDATE CONTACTS SET NUMBER=?;"
|
||||
|
||||
_ = try db.prepare(varQuery1, mobilePhoneNumber).run() // $ Alert // BAD (sensitive data)
|
||||
_ = try db.run(varQuery1, mobilePhoneNumber) // $ Alert // BAD (sensitive data)
|
||||
_ = try db.scalar(varQuery1, mobilePhoneNumber) // $ Alert // BAD (sensitive data)
|
||||
_ = try db.prepare(varQuery1, mobilePhoneNumber).run() // BAD (sensitive data)
|
||||
_ = try db.run(varQuery1, mobilePhoneNumber) // BAD (sensitive data)
|
||||
_ = try db.scalar(varQuery1, mobilePhoneNumber) // BAD (sensitive data)
|
||||
|
||||
let stmt1 = try db.prepare(varQuery1) // GOOD
|
||||
_ = try stmt1.bind(mobilePhoneNumber).run() // $ Alert // BAD (sensitive data)
|
||||
_ = try stmt1.run(mobilePhoneNumber) // $ Alert // BAD (sensitive data)
|
||||
_ = try stmt1.scalar(mobilePhoneNumber) // $ Alert // BAD (sensitive data)
|
||||
_ = try stmt1.bind(mobilePhoneNumber).run() // BAD (sensitive data)
|
||||
_ = try stmt1.run(mobilePhoneNumber) // BAD (sensitive data)
|
||||
_ = try stmt1.scalar(mobilePhoneNumber) // BAD (sensitive data)
|
||||
|
||||
let varQuery2 = "UPDATE CONTACTS SET NUMBER=? WHERE ID=?;"
|
||||
|
||||
_ = try db.prepare(varQuery2, [mobilePhoneNumber, id]).run() // $ Alert // BAD (sensitive data)
|
||||
_ = try db.run(varQuery2, [mobilePhoneNumber, id]) // $ Alert // BAD (sensitive data)
|
||||
_ = try db.scalar(varQuery2, [mobilePhoneNumber, id]) // $ Alert // BAD (sensitive data)
|
||||
_ = try db.prepare(varQuery2, [mobilePhoneNumber, id]).run() // BAD (sensitive data)
|
||||
_ = try db.run(varQuery2, [mobilePhoneNumber, id]) // BAD (sensitive data)
|
||||
_ = try db.scalar(varQuery2, [mobilePhoneNumber, id]) // BAD (sensitive data)
|
||||
|
||||
let stmt2 = try db.prepare(varQuery2) // GOOD
|
||||
_ = try stmt2.bind([mobilePhoneNumber, id]).run() // $ Alert // BAD (sensitive data)
|
||||
_ = try stmt2.run([mobilePhoneNumber, id]) // $ Alert // BAD (sensitive data)
|
||||
_ = try stmt2.scalar([mobilePhoneNumber, id]) // $ Alert // BAD (sensitive data)
|
||||
_ = try stmt2.bind([mobilePhoneNumber, id]).run() // BAD (sensitive data)
|
||||
_ = try stmt2.run([mobilePhoneNumber, id]) // BAD (sensitive data)
|
||||
_ = try stmt2.scalar([mobilePhoneNumber, id]) // BAD (sensitive data)
|
||||
|
||||
let varQuery3 = "UPDATE CONTACTS SET NUMBER=$number WHERE ID=$id;"
|
||||
|
||||
_ = try db.prepare(varQuery3, ["id": id, "number": mobilePhoneNumber]).run() // $ Alert // BAD (sensitive data)
|
||||
_ = try db.run(varQuery3, ["id": id, "number": mobilePhoneNumber]) // $ Alert // BAD (sensitive data)
|
||||
_ = try db.scalar(varQuery3, ["id": id, "number": mobilePhoneNumber]) // $ Alert // BAD (sensitive data)
|
||||
_ = try db.prepare(varQuery3, ["id": id, "number": mobilePhoneNumber]).run() // BAD (sensitive data)
|
||||
_ = try db.run(varQuery3, ["id": id, "number": mobilePhoneNumber]) // BAD (sensitive data)
|
||||
_ = try db.scalar(varQuery3, ["id": id, "number": mobilePhoneNumber]) // BAD (sensitive data)
|
||||
|
||||
let stmt3 = try db.prepare(varQuery3) // GOOD
|
||||
_ = try stmt3.bind(["id": id, "number": mobilePhoneNumber]).run() // $ Alert // BAD (sensitive data)
|
||||
_ = try stmt3.run(["id": id, "number": mobilePhoneNumber]) // $ Alert // BAD (sensitive data)
|
||||
_ = try stmt3.scalar(["id": id, "number": mobilePhoneNumber]) // $ Alert // BAD (sensitive data)
|
||||
_ = try stmt3.bind(["id": id, "number": mobilePhoneNumber]).run() // BAD (sensitive data)
|
||||
_ = try stmt3.run(["id": id, "number": mobilePhoneNumber]) // BAD (sensitive data)
|
||||
_ = try stmt3.scalar(["id": id, "number": mobilePhoneNumber]) // BAD (sensitive data)
|
||||
|
||||
// --- higher level insert / update ---
|
||||
|
||||
@@ -183,20 +183,20 @@ func test_sqlite_swift_api(db: Connection, id: Int, mobilePhoneNumber: String) t
|
||||
let filter = table.filter(idExpr == id) // GOOD
|
||||
|
||||
try db.run(table.insert(idExpr <- id, numberExpr <- "123")) // GOOD
|
||||
try db.run(table.insert(idExpr <- id, numberExpr <- mobilePhoneNumber)) // $ Alert // BAD (sensitive data)
|
||||
try db.run(table.insert(idExpr <- id, numberExpr <- mobilePhoneNumber)) // BAD (sensitive data)
|
||||
|
||||
try db.run(table.update(numberExpr <- "123")) // GOOD
|
||||
try db.run(table.update(numberExpr <- mobilePhoneNumber)) // $ Alert // BAD (sensitive data)
|
||||
try db.run(table.update(numberExpr <- mobilePhoneNumber)) // BAD (sensitive data)
|
||||
try db.run(filter.update(numberExpr <- "123")) // GOOD
|
||||
try db.run(filter.update(numberExpr <- mobilePhoneNumber)) // $ Alert // BAD (sensitive data)
|
||||
try db.run(filter.update(numberExpr <- mobilePhoneNumber)) // BAD (sensitive data)
|
||||
try db.run(table.update(numberExpr <- numberExpr.replace("123", with: "456"))) // GOOD
|
||||
try db.run(table.update(numberExpr <- numberExpr.replace("123", with: mobilePhoneNumber))) // $ Alert // BAD (sensitive data)
|
||||
try db.run(table.update(numberExpr <- numberExpr.replace("123", with: mobilePhoneNumber))) // BAD (sensitive data)
|
||||
// (much more complex query construction is possible in SQLite.swift)
|
||||
|
||||
let goodMany = [[numberExpr <- "456"]]
|
||||
let badMany = [[numberExpr <- mobilePhoneNumber]] // $ Source
|
||||
let badMany = [[numberExpr <- mobilePhoneNumber]]
|
||||
try db.run(table.insertMany(goodMany)) // GOOD
|
||||
try db.run(table.insertMany(badMany)) // $ Alert // BAD (sensitive data)
|
||||
try db.run(table.insertMany(badMany)) // BAD (sensitive data)
|
||||
try db.run(table.insertMany(or: OnConflict.replace, goodMany)) // GOOD
|
||||
try db.run(table.insertMany(or: OnConflict.replace, badMany)) // $ Alert // BAD (sensitive data)
|
||||
try db.run(table.insertMany(or: OnConflict.replace, badMany)) // BAD (sensitive data)
|
||||
}
|
||||
|
||||
@@ -39,12 +39,12 @@ func sqlite3_bind_text(
|
||||
func test_sqlite3_c_api(db: OpaquePointer?, id: Int32, medicalNotes: String) {
|
||||
// --- sensitive data in SQL (in practice these cases may also be SQL injection) ---
|
||||
|
||||
let insertQuery = "INSERT INTO PATIENTS(ID, NOTES) VALUES(\(id), \(medicalNotes));" // $ Source
|
||||
let updateQuery = "UPDATE PATIENTS SET NOTES=\(medicalNotes) WHERE ID=\(id);" // $ Source
|
||||
let insertQuery = "INSERT INTO PATIENTS(ID, NOTES) VALUES(\(id), \(medicalNotes));"
|
||||
let updateQuery = "UPDATE PATIENTS SET NOTES=\(medicalNotes) WHERE ID=\(id);"
|
||||
let deleteQuery = "DELETE FROM PATIENTS WHERE ID=\(id);"
|
||||
|
||||
let _ = sqlite3_exec(db, insertQuery, nil, nil, nil) // $ Alert // BAD (sensitive data)
|
||||
let _ = sqlite3_exec(db, updateQuery, nil, nil, nil) // $ Alert // BAD (sensitive data)
|
||||
let _ = sqlite3_exec(db, insertQuery, nil, nil, nil) // BAD (sensitive data)
|
||||
let _ = sqlite3_exec(db, updateQuery, nil, nil, nil) // BAD (sensitive data)
|
||||
let _ = sqlite3_exec(db, deleteQuery, nil, nil, nil) // GOOD
|
||||
|
||||
// --- sensitive data in bindings ---
|
||||
@@ -55,7 +55,7 @@ func test_sqlite3_c_api(db: OpaquePointer?, id: Int32, medicalNotes: String) {
|
||||
|
||||
if (sqlite3_prepare(db, varQuery, -1, &stmt1, nil) == SQLITE_OK) { // GOOD
|
||||
if (sqlite3_bind_int(stmt1, 1, id) == SQLITE_OK) { // GOOD
|
||||
if (sqlite3_bind_text(stmt1, 2, medicalNotes, -1, SQLITE_TRANSIENT) == SQLITE_OK) { // $ Alert // BAD (sensitive data)
|
||||
if (sqlite3_bind_text(stmt1, 2, medicalNotes, -1, SQLITE_TRANSIENT) == SQLITE_OK) { // BAD (sensitive data)
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,11 +147,11 @@ struct MyEncodable: Encodable {
|
||||
func test1(username: String, password: String, email: String, harmless: String) {
|
||||
// sensitive data in URL
|
||||
|
||||
AF.request("http://example.com/login?p=" + password) // $ Alert
|
||||
AF.request("http://example.com/login?p=" + password) // BAD
|
||||
AF.request("http://example.com/login?h=" + harmless) // GOOD (not sensitive)
|
||||
AF.streamRequest("http://example.com/login?p=" + password) // $ Alert
|
||||
AF.streamRequest("http://example.com/login?p=" + password) // BAD
|
||||
AF.streamRequest("http://example.com/login?h=" + harmless) // GOOD (not sensitive)
|
||||
AF.download("http://example.com/" + email + ".html") // $ Alert
|
||||
AF.download("http://example.com/" + email + ".html") // BAD
|
||||
AF.download("http://example.com/" + harmless + ".html") // GOOD (not sensitive)
|
||||
|
||||
// sensitive data in parameters
|
||||
|
||||
@@ -16,7 +16,7 @@ class NSManagedObject : NSObject
|
||||
class MyManagedObject : NSManagedObject
|
||||
{
|
||||
func setIndirect(value: String) {
|
||||
setValue(value, forKey: "myKey") // $ Alert
|
||||
setValue(value, forKey: "myKey")
|
||||
}
|
||||
|
||||
var myValue: String {
|
||||
@@ -29,7 +29,7 @@ class MyManagedObject : NSManagedObject
|
||||
}
|
||||
}
|
||||
set {
|
||||
setValue(newValue, forKey: "myKey") // $ Alert // [additional result reported here]
|
||||
setValue(newValue, forKey: "myKey") // [additional result reported here]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,23 +45,23 @@ func doSomething(password: String) { }
|
||||
func test1(obj : NSManagedObject, password : String, password_hash : String) {
|
||||
// NSManagedObject methods...
|
||||
|
||||
obj.setValue(password, forKey: "myKey") // $ Alert
|
||||
obj.setValue(password, forKey: "myKey") // BAD
|
||||
obj.setValue(password_hash, forKey: "myKey") // GOOD (not sensitive)
|
||||
|
||||
obj.setPrimitiveValue(password, forKey: "myKey") // $ Alert
|
||||
obj.setPrimitiveValue(password, forKey: "myKey") // BAD
|
||||
obj.setPrimitiveValue(password_hash, forKey: "myKey") // GOOD (not sensitive)
|
||||
}
|
||||
|
||||
func test2(obj : MyManagedObject, password : String, password_file : String) {
|
||||
// MyManagedObject methods...
|
||||
|
||||
obj.setValue(password, forKey: "myKey") // $ Alert
|
||||
obj.setValue(password, forKey: "myKey") // BAD
|
||||
obj.setValue(password_file, forKey: "myKey") // GOOD (not sensitive)
|
||||
|
||||
obj.setIndirect(value: password) // $ Source // BAD [reported on line 19]
|
||||
obj.setIndirect(value: password) // BAD [reported on line 19]
|
||||
obj.setIndirect(value: password_file) // GOOD (not sensitive)
|
||||
|
||||
obj.myValue = password // $ Alert Source // BAD [also reported on line 32]
|
||||
obj.myValue = password // BAD [also reported on line 32]
|
||||
obj.myValue = password_file // GOOD (not sensitive)
|
||||
}
|
||||
|
||||
@@ -74,27 +74,27 @@ func test3(obj : NSManagedObject, x : String) {
|
||||
// alternative evidence of sensitivity...
|
||||
|
||||
obj.setValue(x, forKey: "myKey") // BAD [NOT REPORTED]
|
||||
doSomething(password: x); // $ Source
|
||||
obj.setValue(x, forKey: "myKey") // $ Alert
|
||||
doSomething(password: x);
|
||||
obj.setValue(x, forKey: "myKey") // BAD
|
||||
|
||||
let y = getPassword(); // $ Source
|
||||
obj.setValue(y, forKey: "myKey") // $ Alert
|
||||
let y = getPassword();
|
||||
obj.setValue(y, forKey: "myKey") // BAD
|
||||
|
||||
let z = MyClass()
|
||||
obj.setValue(z.harmless, forKey: "myKey") // GOOD (not sensitive)
|
||||
obj.setValue(z.password, forKey: "myKey") // $ Alert
|
||||
obj.setValue(z.password, forKey: "myKey") // BAD
|
||||
}
|
||||
|
||||
func test4(obj : NSManagedObject, passwd : String) {
|
||||
// sanitizers...
|
||||
|
||||
var x = passwd; // $ Source
|
||||
var y = passwd; // $ Source
|
||||
var z = passwd; // $ Source
|
||||
var x = passwd;
|
||||
var y = passwd;
|
||||
var z = passwd;
|
||||
|
||||
obj.setValue(x, forKey: "myKey") // $ Alert
|
||||
obj.setValue(y, forKey: "myKey") // $ Alert
|
||||
obj.setValue(z, forKey: "myKey") // $ Alert
|
||||
obj.setValue(x, forKey: "myKey") // BAD
|
||||
obj.setValue(y, forKey: "myKey") // BAD
|
||||
obj.setValue(z, forKey: "myKey") // BAD
|
||||
|
||||
x = encrypt(x);
|
||||
hash(data: &y);
|
||||
@@ -125,8 +125,8 @@ func test5(obj : NSManagedObject) {
|
||||
// more variants...
|
||||
|
||||
obj.setValue(createSecureKey(), forKey: "myKey") // BAD [NOT DETECTED]
|
||||
obj.setValue(generateSecretKey(), forKey: "myKey") // $ Alert
|
||||
obj.setValue(getCertificate(), forKey: "myKey") // $ Alert
|
||||
obj.setValue(generateSecretKey(), forKey: "myKey") // BAD
|
||||
obj.setValue(getCertificate(), forKey: "myKey") // BAD
|
||||
|
||||
let gen = KeyGen()
|
||||
let v = gen.generate()
|
||||
|
||||
@@ -34,35 +34,35 @@ func testCoreData2_1(obj: MyManagedObject2, maybeObj: MyManagedObject2?, value:
|
||||
{
|
||||
// @NSManaged fields of an NSManagedObject...
|
||||
obj.myValue = value // GOOD (not sensitive)
|
||||
obj.myValue = bankAccountNo // $ Alert
|
||||
obj.myValue = bankAccountNo // BAD
|
||||
obj.myBankAccountNumber = value // BAD [NOT DETECTED]
|
||||
obj.myBankAccountNumber = bankAccountNo // $ Alert
|
||||
obj.myBankAccountNumber = bankAccountNo // BAD
|
||||
obj.myBankAccountNumber2 = value // BAD [NOT DETECTED]
|
||||
obj.myBankAccountNumber2 = bankAccountNo // $ Alert
|
||||
obj.myBankAccountNumber2 = bankAccountNo // BAD
|
||||
obj.notStoredBankAccountNumber = value // GOOD (not stored in the database)
|
||||
obj.notStoredBankAccountNumber = bankAccountNo // $ Alert // GOOD (not stored in the datbase) [FALSE POSITIVE]
|
||||
obj.notStoredBankAccountNumber = bankAccountNo // GOOD (not stored in the datbase) [FALSE POSITIVE]
|
||||
|
||||
maybeObj?.myValue = value // GOOD (not sensitive)
|
||||
maybeObj?.myValue = bankAccountNo // $ Alert
|
||||
maybeObj?.myValue = bankAccountNo // BAD
|
||||
maybeObj?.myBankAccountNumber = value // BAD [NOT DETECTED]
|
||||
maybeObj?.myBankAccountNumber = bankAccountNo // $ Alert
|
||||
maybeObj?.myBankAccountNumber = bankAccountNo // BAD
|
||||
maybeObj?.myBankAccountNumber2 = value // BAD [NOT DETECTED]
|
||||
maybeObj?.myBankAccountNumber2 = bankAccountNo // $ Alert
|
||||
maybeObj?.myBankAccountNumber2 = bankAccountNo // BAD
|
||||
maybeObj?.notStoredBankAccountNumber = value // GOOD (not stored in the database)
|
||||
maybeObj?.notStoredBankAccountNumber = bankAccountNo // $ Alert // GOOD (not stored in the datbase) [FALSE POSITIVE]
|
||||
maybeObj?.notStoredBankAccountNumber = bankAccountNo // GOOD (not stored in the datbase) [FALSE POSITIVE]
|
||||
}
|
||||
|
||||
class testCoreData2_2 {
|
||||
func myFunc(obj: MyManagedObject2, bankAccountNo: Int) {
|
||||
obj.myBankAccountNumber = bankAccountNo // $ Alert
|
||||
obj.myBankAccountNumber = bankAccountNo // BAD
|
||||
|
||||
if #available(iOS 10.0, *) {
|
||||
obj.myBankAccountNumber = bankAccountNo // $ Alert
|
||||
obj.myBankAccountNumber = bankAccountNo // BAD
|
||||
} else {
|
||||
obj.myBankAccountNumber = bankAccountNo // $ Alert
|
||||
obj.myBankAccountNumber = bankAccountNo // BAD
|
||||
}
|
||||
|
||||
obj.myBankAccountNumber = bankAccountNo // $ Alert
|
||||
obj.myBankAccountNumber = bankAccountNo // BAD
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,31 +76,31 @@ class MyContainer {
|
||||
func testCoreData2_3(dbObj: MyManagedObject2, maybeObj: MyManagedObject2?, container: MyContainer, bankAccountNo: MyContainer, bankAccountNo2: MyContainer!) {
|
||||
dbObj.myValue = container.value // GOOD (not sensitive)
|
||||
dbObj.myValue = container.value2 // GOOD (not sensitive)
|
||||
dbObj.myValue = container.bankAccountNo // $ Alert
|
||||
dbObj.myValue = container.bankAccountNo2 // $ Alert
|
||||
dbObj.myValue = container.bankAccountNo // BAD
|
||||
dbObj.myValue = container.bankAccountNo2 // BAD
|
||||
|
||||
dbObj.myValue = bankAccountNo.value // $ Alert
|
||||
dbObj.myValue = bankAccountNo.value2 // $ Alert
|
||||
dbObj.myValue = bankAccountNo2.value // $ Alert
|
||||
dbObj.myValue = bankAccountNo2.value2 // $ Alert
|
||||
dbObj.myValue = bankAccountNo.value // BAD
|
||||
dbObj.myValue = bankAccountNo.value2 // BAD
|
||||
dbObj.myValue = bankAccountNo2.value // BAD
|
||||
dbObj.myValue = bankAccountNo2.value2 // BAD
|
||||
|
||||
maybeObj?.myValue = container.bankAccountNo // $ Alert
|
||||
maybeObj?.myValue = bankAccountNo.value // $ Alert
|
||||
maybeObj?.myValue = bankAccountNo2.value2 // $ Alert
|
||||
maybeObj?.myValue = container.bankAccountNo // BAD
|
||||
maybeObj?.myValue = bankAccountNo.value // BAD
|
||||
maybeObj?.myValue = bankAccountNo2.value2 // BAD
|
||||
|
||||
var a = bankAccountNo // $ Source // sensitive
|
||||
var a = bankAccountNo // sensitive
|
||||
var b = a.value
|
||||
dbObj.myValue = b // $ Alert
|
||||
dbObj.myValue = b // BAD
|
||||
|
||||
let c = bankAccountNo // $ Source // sensitive
|
||||
let c = bankAccountNo // sensitive
|
||||
var d: MyContainer = MyContainer()
|
||||
d.value = c.value
|
||||
dbObj.myValue = d.value // $ Alert
|
||||
dbObj.myValue = d.value // BAD
|
||||
dbObj.myValue = d.value2 // GOOD
|
||||
|
||||
let e = bankAccountNo // $ Source // sensitive
|
||||
let e = bankAccountNo // sensitive
|
||||
var f: MyContainer?
|
||||
f?.value = e.value
|
||||
dbObj.myValue = e.value // $ Alert
|
||||
dbObj.myValue = e.value2 // $ Alert // GOOD [FALSE POSITIVE]
|
||||
dbObj.myValue = e.value // BAD
|
||||
dbObj.myValue = e.value2 // GOOD [FALSE POSITIVE]
|
||||
}
|
||||
|
||||
@@ -70,145 +70,145 @@ class CommonTableExpression {
|
||||
// --- tests ---
|
||||
|
||||
func test(database: Database, password: String, harmless: String) {
|
||||
let _ = database.allStatements(sql: "", arguments: [password]) // $ Alert
|
||||
let _ = database.allStatements(sql: "", arguments: [password]) // BAD
|
||||
let _ = database.allStatements(sql: "", arguments: [harmless]) // GOOD
|
||||
|
||||
database.execute(sql: "", arguments: [password]) // $ Alert
|
||||
database.execute(sql: "", arguments: [password]) // BAD
|
||||
database.execute(sql: "", arguments: [harmless]) // GOOD
|
||||
}
|
||||
|
||||
func testSqlRequest(password: String, harmless: String) {
|
||||
let _ = SQLRequest(sql: "", arguments: [password]) // $ Alert
|
||||
let _ = SQLRequest(sql: "", arguments: [password]) // BAD
|
||||
let _ = SQLRequest(sql: "", arguments: [harmless]) // GOOD
|
||||
let _ = SQLRequest(sql: "", arguments: [password], adapter: nil) // $ Alert
|
||||
let _ = SQLRequest(sql: "", arguments: [password], adapter: nil) // BAD
|
||||
let _ = SQLRequest(sql: "", arguments: [harmless], adapter: nil) // GOOD
|
||||
let _ = SQLRequest(sql: "", arguments: [password], cached: false) // $ Alert
|
||||
let _ = SQLRequest(sql: "", arguments: [password], cached: false) // BAD
|
||||
let _ = SQLRequest(sql: "", arguments: [harmless], cached: false) // GOOD
|
||||
let _ = SQLRequest(sql: "", arguments: [password], adapter: nil, cached: false) // $ Alert
|
||||
let _ = SQLRequest(sql: "", arguments: [password], adapter: nil, cached: false) // BAD
|
||||
let _ = SQLRequest(sql: "", arguments: [harmless], adapter: nil, cached: false) // GOOD
|
||||
}
|
||||
|
||||
func test(sql: SQL, password: String, harmless: String) {
|
||||
let _ = SQL(sql: "", arguments: [password]) // $ Alert
|
||||
let _ = SQL(sql: "", arguments: [password]) // BAD
|
||||
let _ = SQL(sql: "", arguments: [harmless]) // GOOD
|
||||
|
||||
sql.append(sql: "", arguments: [password]) // $ Alert
|
||||
sql.append(sql: "", arguments: [password]) // BAD
|
||||
sql.append(sql: "", arguments: [harmless]) // GOOD
|
||||
}
|
||||
|
||||
func testSqlStatementCursor(database: Database, password: String, harmless: String) {
|
||||
let _ = SQLStatementCursor(database: database, sql: "", arguments: [password]) // $ Alert
|
||||
let _ = SQLStatementCursor(database: database, sql: "", arguments: [password], prepFlags: 0) // $ Alert
|
||||
let _ = SQLStatementCursor(database: database, sql: "", arguments: [password]) // BAD
|
||||
let _ = SQLStatementCursor(database: database, sql: "", arguments: [password], prepFlags: 0) // BAD
|
||||
let _ = SQLStatementCursor(database: database, sql: "", arguments: [harmless]) // GOOD
|
||||
let _ = SQLStatementCursor(database: database, sql: "", arguments: [harmless], prepFlags: 0) // GOOD
|
||||
}
|
||||
|
||||
func testTableRecord(password: String, harmless: String) {
|
||||
let _ = TableRecord.select(sql: "", arguments: [password]) // $ Alert
|
||||
let _ = TableRecord.select(sql: "", arguments: [password]) // BAD
|
||||
let _ = TableRecord.select(sql: "", arguments: [harmless]) // GOOD
|
||||
let _ = TableRecord.filter(sql: "", arguments: [password]) // $ Alert
|
||||
let _ = TableRecord.filter(sql: "", arguments: [password]) // BAD
|
||||
let _ = TableRecord.filter(sql: "", arguments: [harmless]) // GOOD
|
||||
let _ = TableRecord.order(sql: "", arguments: [password]) // $ Alert
|
||||
let _ = TableRecord.order(sql: "", arguments: [password]) // BAD
|
||||
let _ = TableRecord.order(sql: "", arguments: [harmless]) // GOOD
|
||||
}
|
||||
|
||||
func test(row: Row, stmt: Statement, password: String, harmless: String) {
|
||||
row.fetchCursor(stmt, sql: "", arguments: [password]) // $ Alert
|
||||
row.fetchCursor(stmt, sql: "", arguments: [password]) // BAD
|
||||
row.fetchCursor(stmt, sql: "", arguments: [harmless]) // GOOD
|
||||
row.fetchCursor(stmt, sql: "", arguments: [password], adapter: nil) // $ Alert
|
||||
row.fetchCursor(stmt, sql: "", arguments: [password], adapter: nil) // BAD
|
||||
row.fetchCursor(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
|
||||
|
||||
row.fetchAll(stmt, sql: "", arguments: [password]) // $ Alert
|
||||
row.fetchAll(stmt, sql: "", arguments: [password]) // BAD
|
||||
row.fetchAll(stmt, sql: "", arguments: [harmless]) // GOOD
|
||||
row.fetchAll(stmt, sql: "", arguments: [password], adapter: nil) // $ Alert
|
||||
row.fetchAll(stmt, sql: "", arguments: [password], adapter: nil) // BAD
|
||||
row.fetchAll(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
|
||||
|
||||
row.fetchSet(stmt, sql: "", arguments: [password]) // $ Alert
|
||||
row.fetchSet(stmt, sql: "", arguments: [password]) // BAD
|
||||
row.fetchSet(stmt, sql: "", arguments: [harmless]) // GOOD
|
||||
row.fetchSet(stmt, sql: "", arguments: [password], adapter: nil) // $ Alert
|
||||
row.fetchSet(stmt, sql: "", arguments: [password], adapter: nil) // BAD
|
||||
row.fetchSet(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
|
||||
|
||||
row.fetchOne(stmt, sql: "", arguments: [password]) // $ Alert
|
||||
row.fetchOne(stmt, sql: "", arguments: [password]) // BAD
|
||||
row.fetchOne(stmt, sql: "", arguments: [harmless]) // GOOD
|
||||
row.fetchOne(stmt, sql: "", arguments: [password], adapter: nil) // $ Alert
|
||||
row.fetchOne(stmt, sql: "", arguments: [password], adapter: nil) // BAD
|
||||
row.fetchOne(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
|
||||
}
|
||||
|
||||
func test(databaseValueConvertible: DatabaseValueConvertible, stmt: Statement, password: String, harmless: String) {
|
||||
databaseValueConvertible.fetchCursor(stmt, sql: "", arguments: [password]) // $ Alert
|
||||
databaseValueConvertible.fetchCursor(stmt, sql: "", arguments: [password]) // BAD
|
||||
databaseValueConvertible.fetchCursor(stmt, sql: "", arguments: [harmless]) // GOOD
|
||||
databaseValueConvertible.fetchCursor(stmt, sql: "", arguments: [password], adapter: nil) // $ Alert
|
||||
databaseValueConvertible.fetchCursor(stmt, sql: "", arguments: [password], adapter: nil) // BAD
|
||||
databaseValueConvertible.fetchCursor(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
|
||||
|
||||
databaseValueConvertible.fetchAll(stmt, sql: "", arguments: [password]) // $ Alert
|
||||
databaseValueConvertible.fetchAll(stmt, sql: "", arguments: [password]) // BAD
|
||||
databaseValueConvertible.fetchAll(stmt, sql: "", arguments: [harmless]) // GOOD
|
||||
databaseValueConvertible.fetchAll(stmt, sql: "", arguments: [password], adapter: nil) // $ Alert
|
||||
databaseValueConvertible.fetchAll(stmt, sql: "", arguments: [password], adapter: nil) // BAD
|
||||
databaseValueConvertible.fetchAll(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
|
||||
|
||||
databaseValueConvertible.fetchSet(stmt, sql: "", arguments: [password]) // $ Alert
|
||||
databaseValueConvertible.fetchSet(stmt, sql: "", arguments: [password]) // BAD
|
||||
databaseValueConvertible.fetchSet(stmt, sql: "", arguments: [harmless]) // GOOD
|
||||
databaseValueConvertible.fetchSet(stmt, sql: "", arguments: [password], adapter: nil) // $ Alert
|
||||
databaseValueConvertible.fetchSet(stmt, sql: "", arguments: [password], adapter: nil) // BAD
|
||||
databaseValueConvertible.fetchSet(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
|
||||
|
||||
databaseValueConvertible.fetchOne(stmt, sql: "", arguments: [password]) // $ Alert
|
||||
databaseValueConvertible.fetchOne(stmt, sql: "", arguments: [password]) // BAD
|
||||
databaseValueConvertible.fetchOne(stmt, sql: "", arguments: [harmless]) // GOOD
|
||||
databaseValueConvertible.fetchOne(stmt, sql: "", arguments: [password], adapter: nil) // $ Alert
|
||||
databaseValueConvertible.fetchOne(stmt, sql: "", arguments: [password], adapter: nil) // BAD
|
||||
databaseValueConvertible.fetchOne(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
|
||||
}
|
||||
|
||||
func test(fetchableRecord: FetchableRecord, stmt: Statement, password: String, harmless: String) {
|
||||
fetchableRecord.fetchCursor(stmt, sql: "", arguments: [password]) // $ Alert
|
||||
fetchableRecord.fetchCursor(stmt, arguments: [password]) // $ Alert
|
||||
fetchableRecord.fetchCursor(stmt, sql: "", arguments: [password]) // BAD
|
||||
fetchableRecord.fetchCursor(stmt, arguments: [password]) // BAD
|
||||
fetchableRecord.fetchCursor(stmt, sql: "", arguments: [harmless]) // GOOD
|
||||
fetchableRecord.fetchCursor(stmt, arguments: [harmless]) // GOOD
|
||||
fetchableRecord.fetchCursor(stmt, sql: "", arguments: [password], adapter: nil) // $ Alert
|
||||
fetchableRecord.fetchCursor(stmt, arguments: [password], adapter: nil) // $ Alert
|
||||
fetchableRecord.fetchCursor(stmt, sql: "", arguments: [password], adapter: nil) // BAD
|
||||
fetchableRecord.fetchCursor(stmt, arguments: [password], adapter: nil) // BAD
|
||||
fetchableRecord.fetchCursor(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
|
||||
fetchableRecord.fetchCursor(stmt, arguments: [harmless], adapter: nil) // GOOD
|
||||
|
||||
fetchableRecord.fetchAll(stmt, sql: "", arguments: [password]) // $ Alert
|
||||
fetchableRecord.fetchAll(stmt, arguments: [password]) // $ Alert
|
||||
fetchableRecord.fetchAll(stmt, sql: "", arguments: [password]) // BAD
|
||||
fetchableRecord.fetchAll(stmt, arguments: [password]) // BAD
|
||||
fetchableRecord.fetchAll(stmt, sql: "", arguments: [harmless]) // GOOD
|
||||
fetchableRecord.fetchAll(stmt, arguments: [harmless]) // GOOD
|
||||
fetchableRecord.fetchAll(stmt, sql: "", arguments: [password], adapter: nil) // $ Alert
|
||||
fetchableRecord.fetchAll(stmt, arguments: [password], adapter: nil) // $ Alert
|
||||
fetchableRecord.fetchAll(stmt, sql: "", arguments: [password], adapter: nil) // BAD
|
||||
fetchableRecord.fetchAll(stmt, arguments: [password], adapter: nil) // BAD
|
||||
fetchableRecord.fetchAll(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
|
||||
fetchableRecord.fetchAll(stmt, arguments: [harmless], adapter: nil) // GOOD
|
||||
|
||||
fetchableRecord.fetchSet(stmt, sql: "", arguments: [password]) // $ Alert
|
||||
fetchableRecord.fetchSet(stmt, arguments: [password]) // $ Alert
|
||||
fetchableRecord.fetchSet(stmt, sql: "", arguments: [password]) // BAD
|
||||
fetchableRecord.fetchSet(stmt, arguments: [password]) // BAD
|
||||
fetchableRecord.fetchSet(stmt, sql: "", arguments: [harmless]) // GOOD
|
||||
fetchableRecord.fetchSet(stmt, arguments: [harmless]) // GOOD
|
||||
fetchableRecord.fetchSet(stmt, sql: "", arguments: [password], adapter: nil) // $ Alert
|
||||
fetchableRecord.fetchSet(stmt, arguments: [password], adapter: nil) // $ Alert
|
||||
fetchableRecord.fetchSet(stmt, sql: "", arguments: [password], adapter: nil) // BAD
|
||||
fetchableRecord.fetchSet(stmt, arguments: [password], adapter: nil) // BAD
|
||||
fetchableRecord.fetchSet(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
|
||||
fetchableRecord.fetchSet(stmt, arguments: [harmless], adapter: nil) // GOOD
|
||||
|
||||
fetchableRecord.fetchOne(stmt, sql: "", arguments: [password]) // $ Alert
|
||||
fetchableRecord.fetchOne(stmt, arguments: [password]) // $ Alert
|
||||
fetchableRecord.fetchOne(stmt, sql: "", arguments: [password]) // BAD
|
||||
fetchableRecord.fetchOne(stmt, arguments: [password]) // BAD
|
||||
fetchableRecord.fetchOne(stmt, sql: "", arguments: [harmless]) // GOOD
|
||||
fetchableRecord.fetchOne(stmt, arguments: [harmless]) // GOOD
|
||||
fetchableRecord.fetchOne(stmt, sql: "", arguments: [password], adapter: nil) // $ Alert
|
||||
fetchableRecord.fetchOne(stmt, arguments: [password], adapter: nil) // $ Alert
|
||||
fetchableRecord.fetchOne(stmt, sql: "", arguments: [password], adapter: nil) // BAD
|
||||
fetchableRecord.fetchOne(stmt, arguments: [password], adapter: nil) // BAD
|
||||
fetchableRecord.fetchOne(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
|
||||
fetchableRecord.fetchOne(stmt, arguments: [harmless], adapter: nil) // GOOD
|
||||
}
|
||||
|
||||
func test(stmt: Statement, password: String, harmless: String) {
|
||||
stmt.execute(arguments: [password]) // $ Alert
|
||||
stmt.execute(arguments: [password]) // BAD
|
||||
stmt.execute(arguments: [harmless]) // GOOD
|
||||
|
||||
stmt.setArguments([password]) // $ Alert
|
||||
stmt.setArguments([password]) // BAD
|
||||
stmt.setArguments([harmless]) // GOOD
|
||||
}
|
||||
|
||||
func testCommonTableExpression(password: String, harmless: String) {
|
||||
let _ = CommonTableExpression(named: "", sql: "", arguments: [password]) // $ Alert
|
||||
let _ = CommonTableExpression(named: "", sql: "", arguments: [password]) // BAD
|
||||
let _ = CommonTableExpression(named: "", sql: "", arguments: [harmless]) // GOOD
|
||||
let _ = CommonTableExpression(named: "", columns: nil, sql: "", arguments: [password]) // $ Alert
|
||||
let _ = CommonTableExpression(named: "", columns: nil, sql: "", arguments: [password]) // BAD
|
||||
let _ = CommonTableExpression(named: "", columns: nil, sql: "", arguments: [harmless]) // GOOD
|
||||
let _ = CommonTableExpression(recursive: false, named: "", sql: "", arguments: [password]) // $ Alert
|
||||
let _ = CommonTableExpression(recursive: false, named: "", sql: "", arguments: [password]) // BAD
|
||||
let _ = CommonTableExpression(recursive: false, named: "", sql: "", arguments: [harmless]) // GOOD
|
||||
let _ = CommonTableExpression(recursive: false, named: "", columns: nil, sql: "", arguments: [password]) // $ Alert
|
||||
let _ = CommonTableExpression(recursive: false, named: "", columns: nil, sql: "", arguments: [password]) // BAD
|
||||
let _ = CommonTableExpression(recursive: false, named: "", columns: nil, sql: "", arguments: [harmless]) // GOOD
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ func test1(realm : Realm, myHarmless: String, myPassword : String, myHashedPassw
|
||||
// add objects (within a transaction) ...
|
||||
|
||||
let a = MyRealmSwiftObject()
|
||||
a.data = myPassword // $ Alert
|
||||
a.data = myPassword // BAD
|
||||
realm.add(a)
|
||||
|
||||
let b = MyRealmSwiftObject()
|
||||
@@ -46,7 +46,7 @@ func test1(realm : Realm, myHarmless: String, myPassword : String, myHashedPassw
|
||||
realm.add(b) // GOOD (not sensitive)
|
||||
|
||||
let c = MyRealmSwiftObject()
|
||||
c.data = myPassword // $ Alert
|
||||
c.data = myPassword // BAD
|
||||
realm.create(MyRealmSwiftObject.self, value: c)
|
||||
|
||||
let d = MyRealmSwiftObject()
|
||||
@@ -56,21 +56,21 @@ func test1(realm : Realm, myHarmless: String, myPassword : String, myHashedPassw
|
||||
// retrieve objects ...
|
||||
|
||||
var e = realm.object(ofType: MyRealmSwiftObject.self, forPrimaryKey: "key")
|
||||
e!.data = myPassword // $ Alert
|
||||
e!.data = myPassword // BAD
|
||||
|
||||
var f = realm.object(ofType: MyRealmSwiftObject.self, forPrimaryKey: "key")
|
||||
f!.data = myHashedPassword // GOOD (not sensitive)
|
||||
|
||||
let g = MyRealmSwiftObject()
|
||||
g.data = "" // GOOD (not sensitive)
|
||||
g.data = myPassword // $ Alert
|
||||
g.data = myPassword // BAD
|
||||
g.data = "" // GOOD (not sensitive)
|
||||
|
||||
// MyRealmSwiftObject2...
|
||||
|
||||
let h = MyRealmSwiftObject2()
|
||||
h.harmless = myHarmless // GOOD (not sensitive)
|
||||
h.password = myPassword // $ Alert
|
||||
h.password = myPassword // BAD
|
||||
realm.add(h)
|
||||
}
|
||||
|
||||
|
||||
@@ -15,23 +15,23 @@ class MyRealmSwiftObject3 : Object {
|
||||
|
||||
func test1(o: MyRealmSwiftObject3, myHarmless: String, myPassword: String) {
|
||||
// ...
|
||||
o.data = myPassword // $ Alert
|
||||
o.data = myPassword // BAD
|
||||
o.data = myHarmless
|
||||
// ...
|
||||
}
|
||||
|
||||
func test2(o: MyRealmSwiftObject3, ccn: String, socialSecurityNumber: String, ssn: String, ssn_int: Int, userSSN: String, classno: String) {
|
||||
o.data = socialSecurityNumber // $ Alert
|
||||
o.data = ssn // $ Alert
|
||||
o.data = String(ssn_int) // $ Alert
|
||||
o.data = socialSecurityNumber // BAD
|
||||
o.data = ssn // BAD
|
||||
o.data = String(ssn_int) // BAD
|
||||
o.data = userSSN // BAD [NOT DETECTED]
|
||||
o.data = classno // GOOD
|
||||
}
|
||||
|
||||
func test3(o: MyRealmSwiftObject3, ccn: String, creditCardNumber: String, CCN: String, int_ccn: Int, userCcn: String, succnode: String) {
|
||||
o.data = creditCardNumber // $ Alert
|
||||
o.data = CCN // $ Alert
|
||||
o.data = String(int_ccn) // $ Alert
|
||||
o.data = creditCardNumber // BAD
|
||||
o.data = CCN // BAD
|
||||
o.data = String(int_ccn) // BAD
|
||||
o.data = userCcn // BAD [NOT DETECTED]
|
||||
o.data = succnode // GOOD
|
||||
}
|
||||
|
||||
@@ -26,15 +26,15 @@ func test1(passwordPlain : String, passwordHash : String) {
|
||||
// ...
|
||||
|
||||
nw.send(content: "123456", completion: .idempotent) // GOOD (not sensitive)
|
||||
nw.send(content: passwordPlain, completion: .idempotent) // $ Alert
|
||||
nw.send(content: passwordPlain, completion: .idempotent) // BAD
|
||||
nw.send(content: passwordHash, completion: .idempotent) // GOOD (not sensitive)
|
||||
|
||||
let data1 = Data("123456")
|
||||
let data2 = Data(passwordPlain) // $ Source
|
||||
let data2 = Data(passwordPlain)
|
||||
let data3 = Data(passwordHash)
|
||||
|
||||
nw.send(content: data1, completion: .idempotent) // GOOD (not sensitive)
|
||||
nw.send(content: data2, completion: .idempotent) // $ Alert
|
||||
nw.send(content: data2, completion: .idempotent) // BAD
|
||||
nw.send(content: data3, completion: .idempotent) // GOOD (not sensitive)
|
||||
}
|
||||
|
||||
@@ -55,30 +55,30 @@ struct MyStruct {
|
||||
}
|
||||
|
||||
func test2(password : String, license_key: String, ms: MyStruct, connection : NWConnection) {
|
||||
let str1 = password // $ Source
|
||||
let str2 = password + " " // $ Source
|
||||
let str3 = pad(password) // $ Source
|
||||
let str1 = password
|
||||
let str2 = password + " "
|
||||
let str3 = pad(password)
|
||||
let str4 = aes_crypt(password)
|
||||
let str5 = pad(aes_crypt(password))
|
||||
let str6 = aes_crypt(pad(password))
|
||||
|
||||
connection.send(content: str1, completion: .idempotent) // $ Alert
|
||||
connection.send(content: str2, completion: .idempotent) // $ Alert
|
||||
connection.send(content: str3, completion: .idempotent) // $ Alert
|
||||
connection.send(content: str1, completion: .idempotent) // BAD
|
||||
connection.send(content: str2, completion: .idempotent) // BAD
|
||||
connection.send(content: str3, completion: .idempotent) // BAD
|
||||
connection.send(content: str4, completion: .idempotent) // GOOD (encrypted)
|
||||
connection.send(content: str5, completion: .idempotent) // GOOD (encrypted)
|
||||
connection.send(content: str6, completion: .idempotent) // GOOD (encrypted)
|
||||
connection.send(content: license_key, completion: .idempotent) // $ Alert
|
||||
connection.send(content: ms.mobileNumber, completion: .idempotent) // $ Alert
|
||||
connection.send(content: license_key, completion: .idempotent) // BAD
|
||||
connection.send(content: ms.mobileNumber, completion: .idempotent) // BAD
|
||||
connection.send(content: ms.mobileUrl, completion: .idempotent) // GOOD (not sensitive)
|
||||
connection.send(content: ms.mobilePlayer, completion: .idempotent) // GOOD (not sensitive)
|
||||
connection.send(content: ms.passwordFeatureEnabled, completion: .idempotent) // GOOD (not sensitive)
|
||||
connection.send(content: ms.Telephone, completion: .idempotent) // $ Alert
|
||||
connection.send(content: ms.birth_day, completion: .idempotent) // $ Alert
|
||||
connection.send(content: ms.CarePlanID, completion: .idempotent) // $ Alert
|
||||
connection.send(content: ms.BankCardNo, completion: .idempotent) // $ Alert
|
||||
connection.send(content: ms.MyCreditRating, completion: .idempotent) // $ Alert
|
||||
connection.send(content: ms.OneTimeCode, completion: .idempotent) // $ Alert
|
||||
connection.send(content: ms.Telephone, completion: .idempotent) // BAD
|
||||
connection.send(content: ms.birth_day, completion: .idempotent) // BAD
|
||||
connection.send(content: ms.CarePlanID, completion: .idempotent) // BAD
|
||||
connection.send(content: ms.BankCardNo, completion: .idempotent) // BAD
|
||||
connection.send(content: ms.MyCreditRating, completion: .idempotent) // BAD
|
||||
connection.send(content: ms.OneTimeCode, completion: .idempotent) // BAD
|
||||
}
|
||||
|
||||
struct MyOuter {
|
||||
@@ -91,6 +91,6 @@ struct MyOuter {
|
||||
}
|
||||
|
||||
func test3(mo : MyOuter, connection : NWConnection) {
|
||||
connection.send(content: mo.password.value, completion: .idempotent) // $ Alert
|
||||
connection.send(content: mo.password.value, completion: .idempotent) // BAD
|
||||
connection.send(content: mo.harmless.value, completion: .idempotent) // GOOD
|
||||
}
|
||||
|
||||
@@ -36,22 +36,22 @@ func setMyString(str: String) { myString = str }
|
||||
func getMyString() -> String { return myString }
|
||||
|
||||
func test1(passwd : String, encrypted_passwd : String, account_no : String, credit_card_no : String) {
|
||||
_ = URL(string: "http://example.com/login?p=" + passwd); // $ Alert
|
||||
_ = URL(string: "http://example.com/login?p=" + passwd); // BAD
|
||||
_ = URL(string: "http://example.com/login?p=" + encrypted_passwd); // GOOD (not sensitive)
|
||||
_ = URL(string: "http://example.com/login?ac=" + account_no); // $ Alert
|
||||
_ = URL(string: "http://example.com/login?cc=" + credit_card_no); // $ Alert
|
||||
_ = URL(string: "http://example.com/login?ac=" + account_no); // BAD
|
||||
_ = URL(string: "http://example.com/login?cc=" + credit_card_no); // BAD
|
||||
|
||||
let base = URL(string: "http://example.com/"); // GOOD (not sensitive)
|
||||
_ = URL(string: "abc", relativeTo: base); // GOOD (not sensitive)
|
||||
let f = URL(string: passwd, relativeTo: base); // $ Alert
|
||||
let f = URL(string: passwd, relativeTo: base); // BAD
|
||||
_ = URL(string: "abc", relativeTo: f); // BAD (reported on line above)
|
||||
|
||||
let e_mail = myString
|
||||
_ = URL(string: "http://example.com/login?em=" + e_mail); // $ Alert
|
||||
_ = URL(string: "http://example.com/login?em=" + e_mail); // BAD
|
||||
let a_homeaddr_z = getMyString()
|
||||
_ = URL(string: "http://example.com/login?home=" + a_homeaddr_z); // $ Alert
|
||||
_ = URL(string: "http://example.com/login?home=" + a_homeaddr_z); // BAD
|
||||
let resident_ID = getMyString()
|
||||
_ = URL(string: "http://example.com/login?id=" + resident_ID); // $ Alert
|
||||
_ = URL(string: "http://example.com/login?id=" + resident_ID); // BAD
|
||||
}
|
||||
|
||||
func get_private_key() -> String { return "" }
|
||||
@@ -70,9 +70,9 @@ func test2() {
|
||||
_ = URL(string: "http://example.com/login?key=" + get_aes_key()); // BAD [NOT DETECTED]
|
||||
_ = URL(string: "http://example.com/login?key=" + get_aws_key()); // BAD [NOT DETECTED]
|
||||
_ = URL(string: "http://example.com/login?key=" + get_access_key()); // BAD [NOT DETECTED]
|
||||
_ = URL(string: "http://example.com/login?key=" + get_secret_key()); // $ Alert
|
||||
_ = URL(string: "http://example.com/login?key=" + get_secret_key()); // BAD
|
||||
_ = URL(string: "http://example.com/login?key=" + get_key_press()); // GOOD (not sensitive)
|
||||
_ = URL(string: "http://example.com/login?cert=" + get_cert_string()); // $ Alert
|
||||
_ = URL(string: "http://example.com/login?cert=" + get_cert_string()); // BAD
|
||||
_ = URL(string: "http://example.com/login?certain=" + get_certain()); // GOOD (not sensitive)
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ func test3() {
|
||||
_ = URL(string: "http://example.com/login?key=\(priv_key)"); // BAD [NOT DETECTED]
|
||||
_ = URL(string: "http://example.com/login?key=\(private_key)"); // BAD [NOT DETECTED]
|
||||
_ = URL(string: "http://example.com/login?key=\(pub_key)"); // GOOD (not sensitive)
|
||||
_ = URL(string: "http://example.com/login?cert=\(certificate)"); // $ Alert
|
||||
_ = URL(string: "http://example.com/login?cert=\(certificate)"); // BAD
|
||||
_ = URL(string: "http://example.com/login?tok=\(secure_token)"); // BAD [NOT DETECTED]
|
||||
_ = URL(string: "http://example.com/login?tok=\(access_token)"); // BAD [NOT DETECTED]
|
||||
_ = URL(string: "http://example.com/login?tok=\(auth_token)"); // BAD [NOT DETECTED]
|
||||
@@ -101,9 +101,9 @@ func test3() {
|
||||
}
|
||||
|
||||
func test4(key: SecKey) {
|
||||
if let data = SecKeyCopyExternalRepresentation(key, nil) as? Data { // $ Source
|
||||
if let data = SecKeyCopyExternalRepresentation(key, nil) as? Data {
|
||||
if let string = String(data: data, encoding: .utf8) {
|
||||
_ = URL(string: "http://example.com/login?tok=\(string)"); // $ Alert
|
||||
_ = URL(string: "http://example.com/login?tok=\(string)"); // BAD
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,14 +113,14 @@ func test5() {
|
||||
let email = get_string()
|
||||
let secret_key = get_string()
|
||||
|
||||
_ = URL(string: "http://example.com/login?email=\(email)"); // $ Alert
|
||||
_ = URL(string: "http://example.com/login?email=\(email)"); // BAD
|
||||
_ = URL(string: "mailto:\(email)"); // GOOD (revealing your e-amil address in an e-mail is expected)
|
||||
_ = URL(string: "mailto:info@example.com?subject=\(secret_key)"); // BAD [NOT DETECTED]
|
||||
_ = URL(string: "mailto:info@example.com?subject=foo&cc=\(email)"); // GOOD
|
||||
|
||||
let phone_number = get_string()
|
||||
|
||||
_ = URL(string: "http://example.com/profile?tel=\(phone_number)"); // $ Alert
|
||||
_ = URL(string: "http://example.com/profile?tel=\(phone_number)"); // BAD
|
||||
_ = URL(string: "tel:\(phone_number)") // GOOD
|
||||
_ = URL(string: "telprompt:\(phone_number)") // GOOD
|
||||
_ = URL(string: "callto:\(phone_number)") // GOOD
|
||||
@@ -129,5 +129,5 @@ func test5() {
|
||||
let account_no = get_string()
|
||||
|
||||
_ = URL(string: "file:///foo/bar/\(account_no).csv") // GOOD (local, so not transmitted)
|
||||
_ = URL(string: "ftp://example.com/\(account_no).csv") // $ Alert
|
||||
_ = URL(string: "ftp://example.com/\(account_no).csv") // BAD
|
||||
}
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
query: queries/Security/CWE-312/CleartextStoragePreferences.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
queries/Security/CWE-312/CleartextStoragePreferences.ql
|
||||
|
||||
@@ -25,7 +25,7 @@ func doSomething(password: String) { }
|
||||
func test1(password: String, passwordHash : String) {
|
||||
let store = NSUbiquitousKeyValueStore.default
|
||||
|
||||
store.set(password, forKey: "myKey") // $ Alert
|
||||
store.set(password, forKey: "myKey") // BAD
|
||||
store.set(passwordHash, forKey: "myKey") // GOOD (not sensitive)
|
||||
}
|
||||
|
||||
@@ -38,27 +38,27 @@ func test3(x: String) {
|
||||
// alternative evidence of sensitivity...
|
||||
|
||||
NSUbiquitousKeyValueStore.default.set(x, forKey: "myKey") // BAD [NOT REPORTED]
|
||||
doSomething(password: x); // $ Source
|
||||
NSUbiquitousKeyValueStore.default.set(x, forKey: "myKey") // $ Alert
|
||||
doSomething(password: x);
|
||||
NSUbiquitousKeyValueStore.default.set(x, forKey: "myKey") // BAD
|
||||
|
||||
let y = getPassword(); // $ Source
|
||||
NSUbiquitousKeyValueStore.default.set(y, forKey: "myKey") // $ Alert
|
||||
let y = getPassword();
|
||||
NSUbiquitousKeyValueStore.default.set(y, forKey: "myKey") // BAD
|
||||
|
||||
let z = MyClass()
|
||||
NSUbiquitousKeyValueStore.default.set(z.harmless, forKey: "myKey") // GOOD (not sensitive)
|
||||
NSUbiquitousKeyValueStore.default.set(z.password, forKey: "myKey") // $ Alert
|
||||
NSUbiquitousKeyValueStore.default.set(z.password, forKey: "myKey") // BAD
|
||||
}
|
||||
|
||||
func test4(passwd: String) {
|
||||
// sanitizers...
|
||||
|
||||
var x = passwd; // $ Source
|
||||
var y = passwd; // $ Source
|
||||
var z = passwd; // $ Source
|
||||
var x = passwd;
|
||||
var y = passwd;
|
||||
var z = passwd;
|
||||
|
||||
NSUbiquitousKeyValueStore.default.set(x, forKey: "myKey") // $ Alert
|
||||
NSUbiquitousKeyValueStore.default.set(y, forKey: "myKey") // $ Alert
|
||||
NSUbiquitousKeyValueStore.default.set(z, forKey: "myKey") // $ Alert
|
||||
NSUbiquitousKeyValueStore.default.set(x, forKey: "myKey") // BAD
|
||||
NSUbiquitousKeyValueStore.default.set(y, forKey: "myKey") // BAD
|
||||
NSUbiquitousKeyValueStore.default.set(z, forKey: "myKey") // BAD
|
||||
|
||||
x = encrypt(x);
|
||||
hash(data: &y);
|
||||
|
||||
@@ -25,7 +25,7 @@ func doSomething(password: String) { }
|
||||
func test1(password: String, passwordHash : String) {
|
||||
let defaults = UserDefaults.standard
|
||||
|
||||
defaults.set(password, forKey: "myKey") // $ Alert
|
||||
defaults.set(password, forKey: "myKey") // BAD
|
||||
defaults.set(passwordHash, forKey: "myKey") // GOOD (not sensitive)
|
||||
}
|
||||
|
||||
@@ -38,27 +38,27 @@ func test3(x: String) {
|
||||
// alternative evidence of sensitivity...
|
||||
|
||||
UserDefaults.standard.set(x, forKey: "myKey") // BAD [NOT REPORTED]
|
||||
doSomething(password: x); // $ Source
|
||||
UserDefaults.standard.set(x, forKey: "myKey") // $ Alert
|
||||
doSomething(password: x);
|
||||
UserDefaults.standard.set(x, forKey: "myKey") // BAD
|
||||
|
||||
let y = getPassword(); // $ Source
|
||||
UserDefaults.standard.set(y, forKey: "myKey") // $ Alert
|
||||
let y = getPassword();
|
||||
UserDefaults.standard.set(y, forKey: "myKey") // BAD
|
||||
|
||||
let z = MyClass()
|
||||
UserDefaults.standard.set(z.harmless, forKey: "myKey") // GOOD (not sensitive)
|
||||
UserDefaults.standard.set(z.password, forKey: "myKey") // $ Alert
|
||||
UserDefaults.standard.set(z.password, forKey: "myKey") // BAD
|
||||
}
|
||||
|
||||
func test4(passwd: String) {
|
||||
// sanitizers...
|
||||
|
||||
var x = passwd; // $ Source
|
||||
var y = passwd; // $ Source
|
||||
var z = passwd; // $ Source
|
||||
var x = passwd;
|
||||
var y = passwd;
|
||||
var z = passwd;
|
||||
|
||||
UserDefaults.standard.set(x, forKey: "myKey") // $ Alert
|
||||
UserDefaults.standard.set(y, forKey: "myKey") // $ Alert
|
||||
UserDefaults.standard.set(z, forKey: "myKey") // $ Alert
|
||||
UserDefaults.standard.set(x, forKey: "myKey") // BAD
|
||||
UserDefaults.standard.set(y, forKey: "myKey") // BAD
|
||||
UserDefaults.standard.set(z, forKey: "myKey") // BAD
|
||||
|
||||
x = encrypt(x);
|
||||
hash(data: &y);
|
||||
@@ -79,6 +79,6 @@ struct MyOuter {
|
||||
}
|
||||
|
||||
func test5(mo : MyOuter) {
|
||||
UserDefaults.standard.set(mo.password.value, forKey: "myKey") // $ Alert
|
||||
UserDefaults.standard.set(mo.password.value, forKey: "myKey") // BAD
|
||||
UserDefaults.standard.set(mo.harmless.value, forKey: "myKey") // GOOD
|
||||
}
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
query: queries/Security/CWE-327/ECBEncryption.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
queries/Security/CWE-327/ECBEncryption.ql
|
||||
@@ -36,7 +36,7 @@ func getRandomArray() -> Array<UInt8> {
|
||||
}
|
||||
|
||||
func getECBBlockMode() -> BlockMode {
|
||||
return ECB() // $ Source
|
||||
return ECB()
|
||||
}
|
||||
|
||||
func getCBCBlockMode() -> BlockMode {
|
||||
@@ -47,18 +47,18 @@ func getCBCBlockMode() -> BlockMode {
|
||||
|
||||
func test1() {
|
||||
let key: Array<UInt8> = [0x2a, 0x3a, 0x80, 0x05, 0xaf, 0x46, 0x58, 0x2d, 0x66, 0x52, 0x10, 0xae, 0x86, 0xd3, 0x8e, 0x8f]
|
||||
let ecb = ECB() // $ Source
|
||||
let ecb = ECB()
|
||||
let iv = getRandomArray()
|
||||
let cbc = CBC(iv: iv)
|
||||
let padding = Padding.noPadding
|
||||
|
||||
// AES test cases
|
||||
let ab1 = AES(key: key, blockMode: ecb, padding: padding) // $ Alert
|
||||
let ab2 = AES(key: key, blockMode: ecb) // $ Alert
|
||||
let ab3 = AES(key: key, blockMode: ECB(), padding: padding) // $ Alert
|
||||
let ab4 = AES(key: key, blockMode: ECB()) // $ Alert
|
||||
let ab5 = AES(key: key, blockMode: getECBBlockMode(), padding: padding) // $ Alert
|
||||
let ab6 = AES(key: key, blockMode: getECBBlockMode()) // $ Alert
|
||||
let ab1 = AES(key: key, blockMode: ecb, padding: padding) // BAD
|
||||
let ab2 = AES(key: key, blockMode: ecb) // BAD
|
||||
let ab3 = AES(key: key, blockMode: ECB(), padding: padding) // BAD
|
||||
let ab4 = AES(key: key, blockMode: ECB()) // BAD
|
||||
let ab5 = AES(key: key, blockMode: getECBBlockMode(), padding: padding) // BAD
|
||||
let ab6 = AES(key: key, blockMode: getECBBlockMode()) // BAD
|
||||
|
||||
let ag1 = AES(key: key, blockMode: cbc, padding: padding) // GOOD
|
||||
let ag2 = AES(key: key, blockMode: cbc) // GOOD
|
||||
@@ -68,9 +68,9 @@ func test1() {
|
||||
let ag6 = AES(key: key, blockMode: getCBCBlockMode()) // GOOD
|
||||
|
||||
// Blowfish test cases
|
||||
let bb1 = Blowfish(key: key, blockMode: ecb, padding: padding) // $ Alert
|
||||
let bb2 = Blowfish(key: key, blockMode: ECB(), padding: padding) // $ Alert
|
||||
let bb3 = Blowfish(key: key, blockMode: getECBBlockMode(), padding: padding) // $ Alert
|
||||
let bb1 = Blowfish(key: key, blockMode: ecb, padding: padding) // BAD
|
||||
let bb2 = Blowfish(key: key, blockMode: ECB(), padding: padding) // BAD
|
||||
let bb3 = Blowfish(key: key, blockMode: getECBBlockMode(), padding: padding) // BAD
|
||||
|
||||
let bg1 = Blowfish(key: key, blockMode: cbc, padding: padding) // GOOD
|
||||
let bg2 = Blowfish(key: key, blockMode: CBC(iv: iv), padding: padding) // GOOD
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
query: queries/Security/CWE-328/WeakPasswordHashing.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
queries/Security/CWE-328/WeakPasswordHashing.ql
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
query: queries/Security/CWE-328/WeakSensitiveDataHashing.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
queries/Security/CWE-328/WeakSensitiveDataHashing.ql
|
||||
|
||||
@@ -81,43 +81,43 @@ enum Insecure {
|
||||
// --- tests ---
|
||||
|
||||
func testHashMethods(passwd : UnsafeRawBufferPointer, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) {
|
||||
var hash = Crypto.Insecure.MD5.hash(data: passwd) // $ Alert
|
||||
hash = Crypto.Insecure.MD5.hash(bufferPointer: passwd) // $ Alert
|
||||
hash = Crypto.Insecure.MD5.hash(data: cert) // $ Alert
|
||||
var hash = Crypto.Insecure.MD5.hash(data: passwd) // BAD
|
||||
hash = Crypto.Insecure.MD5.hash(bufferPointer: passwd) // BAD
|
||||
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) // $ Alert
|
||||
hash = Crypto.Insecure.MD5.hash(data: credit_card_no) // $ Alert
|
||||
hash = Crypto.Insecure.MD5.hash(data: account_no) // BAD
|
||||
hash = Crypto.Insecure.MD5.hash(data: credit_card_no) // BAD
|
||||
|
||||
hash = Insecure.MD5.hash(data: passwd) // $ Alert
|
||||
hash = Insecure.MD5.hash(bufferPointer: passwd) // $ Alert
|
||||
hash = Insecure.MD5.hash(data: cert) // $ Alert
|
||||
hash = Insecure.MD5.hash(data: passwd) // BAD
|
||||
hash = Insecure.MD5.hash(bufferPointer: passwd) // BAD
|
||||
hash = Insecure.MD5.hash(data: cert) // BAD
|
||||
hash = Insecure.MD5.hash(data: encrypted_passwd) // GOOD (not sensitive)
|
||||
hash = Insecure.MD5.hash(data: account_no) // $ Alert
|
||||
hash = Insecure.MD5.hash(data: credit_card_no) // $ Alert
|
||||
hash = Insecure.MD5.hash(data: account_no) // BAD
|
||||
hash = Insecure.MD5.hash(data: credit_card_no) // BAD
|
||||
|
||||
hash = Crypto.Insecure.SHA1.hash(data: passwd) // $ Alert
|
||||
hash = Crypto.Insecure.SHA1.hash(bufferPointer: passwd) // $ Alert
|
||||
hash = Crypto.Insecure.SHA1.hash(data: cert) // $ Alert
|
||||
hash = Crypto.Insecure.SHA1.hash(data: passwd) // BAD
|
||||
hash = Crypto.Insecure.SHA1.hash(bufferPointer: passwd) // BAD
|
||||
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) // $ Alert
|
||||
hash = Crypto.Insecure.SHA1.hash(data: credit_card_no) // $ Alert
|
||||
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) // $ Alert // BAD, not a computationally expensive hash
|
||||
hash = Crypto.SHA256.hash(bufferPointer: passwd) // $ Alert // BAD, not a computationally expensive hash
|
||||
hash = Crypto.SHA256.hash(data: passwd) // BAD, not a computationally expensive hash
|
||||
hash = Crypto.SHA256.hash(bufferPointer: passwd) // BAD, not a computationally expensive hash
|
||||
hash = Crypto.SHA256.hash(data: cert) // GOOD, computationally expensive hash not required
|
||||
hash = Crypto.SHA256.hash(data: encrypted_passwd) // GOOD, not sensitive
|
||||
hash = Crypto.SHA256.hash(data: account_no) // GOOD, computationally expensive hash not required
|
||||
hash = Crypto.SHA256.hash(data: credit_card_no) // GOOD, computationally expensive hash not required
|
||||
|
||||
hash = Crypto.SHA384.hash(data: passwd) // $ Alert // BAD, not a computationally expensive hash
|
||||
hash = Crypto.SHA384.hash(bufferPointer: passwd) // $ Alert // BAD, not a computationally expensive hash
|
||||
hash = Crypto.SHA384.hash(data: passwd) // BAD, not a computationally expensive hash
|
||||
hash = Crypto.SHA384.hash(bufferPointer: passwd) // BAD, not a computationally expensive hash
|
||||
hash = Crypto.SHA384.hash(data: cert) // GOOD, computationally expensive hash not required
|
||||
hash = Crypto.SHA384.hash(data: encrypted_passwd) // GOOD, not sensitive
|
||||
hash = Crypto.SHA384.hash(data: account_no) // GOOD, computationally expensive hash not required
|
||||
hash = Crypto.SHA384.hash(data: credit_card_no) // GOOD, computationally expensive hash not required
|
||||
|
||||
hash = Crypto.SHA512.hash(data: passwd) // $ Alert // BAD, not a computationally expensive hash
|
||||
hash = Crypto.SHA512.hash(bufferPointer: passwd) // $ Alert // BAD, not a computationally expensive hash
|
||||
hash = Crypto.SHA512.hash(data: passwd) // BAD, not a computationally expensive hash
|
||||
hash = Crypto.SHA512.hash(bufferPointer: passwd) // BAD, not a computationally expensive hash
|
||||
hash = Crypto.SHA512.hash(data: cert) // GOOD, computationally expensive hash not required
|
||||
hash = Crypto.SHA512.hash(data: encrypted_passwd) // GOOD, not sensitive
|
||||
hash = Crypto.SHA512.hash(data: account_no) // GOOD, computationally expensive hash not required
|
||||
@@ -126,25 +126,25 @@ 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) // $ Alert
|
||||
hash.update(data: cert) // $ Alert
|
||||
hash.update(data: passwd) // BAD
|
||||
hash.update(data: cert) // BAD
|
||||
hash.update(data: encrypted_passwd) // GOOD (not sensitive)
|
||||
hash.update(data: account_no) // $ Alert
|
||||
hash.update(data: credit_card_no) // $ Alert
|
||||
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) // $ Alert
|
||||
hash.update(data: cert) // $ Alert
|
||||
hash.update(data: passwd) // BAD
|
||||
hash.update(data: cert) // BAD
|
||||
hash.update(data: encrypted_passwd) // GOOD (not sensitive)
|
||||
hash.update(data: account_no) // $ Alert
|
||||
hash.update(data: credit_card_no) // $ Alert
|
||||
hash.update(data: account_no) // BAD
|
||||
hash.update(data: credit_card_no) // BAD
|
||||
}
|
||||
|
||||
func testSHA256UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) {
|
||||
var hash = Crypto.SHA256()
|
||||
hash.update(data: passwd) // $ Alert // BAD, not a computationally expensive hash
|
||||
hash.update(data: passwd) // BAD, not a computationally expensive hash
|
||||
hash.update(data: cert) // GOOD
|
||||
hash.update(data: encrypted_passwd) // GOOD (not sensitive)
|
||||
hash.update(data: account_no) // GOOD
|
||||
@@ -153,7 +153,7 @@ func testSHA256UpdateWithData(passwd : String, cert: String, encrypted_passwd :
|
||||
|
||||
func testSHA384UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) {
|
||||
var hash = Crypto.SHA384()
|
||||
hash.update(data: passwd) // $ Alert // BAD, not a computationally expensive hash
|
||||
hash.update(data: passwd) // BAD, not a computationally expensive hash
|
||||
hash.update(data: cert) // GOOD
|
||||
hash.update(data: encrypted_passwd) // GOOD (not sensitive)
|
||||
hash.update(data: account_no) // GOOD
|
||||
@@ -162,7 +162,7 @@ func testSHA384UpdateWithData(passwd : String, cert: String, encrypted_passwd :
|
||||
|
||||
func testSHA512UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) {
|
||||
var hash = Crypto.SHA512()
|
||||
hash.update(data: passwd) // $ Alert // BAD, not a computationally expensive hash
|
||||
hash.update(data: passwd) // BAD, not a computationally expensive hash
|
||||
hash.update(data: cert) // GOOD
|
||||
hash.update(data: encrypted_passwd) // GOOD (not sensitive)
|
||||
hash.update(data: account_no) // GOOD
|
||||
@@ -171,25 +171,25 @@ 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) // $ Alert
|
||||
hash.update(bufferPointer: cert) // $ Alert
|
||||
hash.update(bufferPointer: passwd) // BAD
|
||||
hash.update(bufferPointer: cert) // BAD
|
||||
hash.update(bufferPointer: encrypted_passwd) // GOOD (not sensitive)
|
||||
hash.update(bufferPointer: account_no) // $ Alert
|
||||
hash.update(bufferPointer: credit_card_no) // $ Alert
|
||||
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) // $ Alert
|
||||
hash.update(bufferPointer: cert) // $ Alert
|
||||
hash.update(bufferPointer: passwd) // BAD
|
||||
hash.update(bufferPointer: cert) // BAD
|
||||
hash.update(bufferPointer: encrypted_passwd) // GOOD (not sensitive)
|
||||
hash.update(bufferPointer: account_no) // $ Alert
|
||||
hash.update(bufferPointer: credit_card_no) // $ Alert
|
||||
hash.update(bufferPointer: account_no) // BAD
|
||||
hash.update(bufferPointer: credit_card_no) // BAD
|
||||
}
|
||||
|
||||
func testSHA256UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer, cert: UnsafeRawBufferPointer, encrypted_passwd : UnsafeRawBufferPointer, account_no : UnsafeRawBufferPointer, credit_card_no : UnsafeRawBufferPointer) {
|
||||
var hash = Crypto.SHA256()
|
||||
hash.update(bufferPointer: passwd) // $ Alert // BAD, not a computationally expensive hash
|
||||
hash.update(bufferPointer: passwd) // BAD, not a computationally expensive hash
|
||||
hash.update(bufferPointer: cert) // GOOD
|
||||
hash.update(bufferPointer: encrypted_passwd) // GOOD (not sensitive)
|
||||
hash.update(bufferPointer: account_no) // GOOD
|
||||
@@ -198,7 +198,7 @@ func testSHA256UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer,
|
||||
|
||||
func testSHA384UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer, cert: UnsafeRawBufferPointer, encrypted_passwd : UnsafeRawBufferPointer, account_no : UnsafeRawBufferPointer, credit_card_no : UnsafeRawBufferPointer) {
|
||||
var hash = Crypto.SHA384()
|
||||
hash.update(bufferPointer: passwd) // $ Alert // BAD, not a computationally expensive hash
|
||||
hash.update(bufferPointer: passwd) // BAD, not a computationally expensive hash
|
||||
hash.update(bufferPointer: cert) // GOOD
|
||||
hash.update(bufferPointer: encrypted_passwd) // GOOD (not sensitive)
|
||||
hash.update(bufferPointer: account_no) // GOOD
|
||||
@@ -207,7 +207,7 @@ func testSHA384UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer,
|
||||
|
||||
func testSHA512UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer, cert: UnsafeRawBufferPointer, encrypted_passwd : UnsafeRawBufferPointer, account_no : UnsafeRawBufferPointer, credit_card_no : UnsafeRawBufferPointer) {
|
||||
var hash = Crypto.SHA512()
|
||||
hash.update(bufferPointer: passwd) // $ Alert // BAD, not a computationally expensive hash
|
||||
hash.update(bufferPointer: passwd) // BAD, not a computationally expensive hash
|
||||
hash.update(bufferPointer: cert) // GOOD
|
||||
hash.update(bufferPointer: encrypted_passwd) // GOOD (not sensitive)
|
||||
hash.update(bufferPointer: account_no) // GOOD
|
||||
@@ -217,30 +217,30 @@ func testSHA512UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer,
|
||||
func testBadExample(passwordString: String) {
|
||||
// this is the "bad" example from the .qhelp
|
||||
let passwordData = Data(passwordString.utf8)
|
||||
let passwordHash = Crypto.SHA512.hash(data: passwordData) // $ Alert // BAD, not a computationally expensive hash
|
||||
let passwordHash = Crypto.SHA512.hash(data: passwordData) // BAD, not a computationally expensive hash
|
||||
|
||||
// ...
|
||||
|
||||
if Crypto.SHA512.hash(data: Data(passwordString.utf8)) == passwordHash { // $ Alert // BAD, not a computationally expensive hash
|
||||
if Crypto.SHA512.hash(data: Data(passwordString.utf8)) == passwordHash { // BAD, not a computationally expensive hash
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
func testWithFlowAndMetatypes(cardNumber: String) {
|
||||
let value1 = Data(cardNumber.utf8); // $ Source
|
||||
let _digest1 = Insecure.MD5.hash(data: value1); // $ Alert
|
||||
let value1 = Data(cardNumber.utf8);
|
||||
let _digest1 = Insecure.MD5.hash(data: value1); // BAD
|
||||
|
||||
let value2 = Data(cardNumber.utf8); // $ Source
|
||||
let value2 = Data(cardNumber.utf8);
|
||||
let hasher2 = Insecure.MD5.self; // metatype
|
||||
let _digest2 = hasher2.hash(data: value2); // $ Alert
|
||||
let _digest2 = hasher2.hash(data: value2); // BAD
|
||||
|
||||
let value3 = Data(cardNumber.utf8); // $ Source
|
||||
let _digest3 = (Insecure.MD5.self).hash(data: value3); // $ Alert
|
||||
let value3 = Data(cardNumber.utf8);
|
||||
let _digest3 = (Insecure.MD5.self).hash(data: value3); // BAD
|
||||
|
||||
let value4 = Data(cardNumber.utf8); // $ Source
|
||||
let value4 = Data(cardNumber.utf8);
|
||||
testReceiver1(value: value4);
|
||||
|
||||
let value5 = Data(cardNumber.utf8); // $ Source
|
||||
let value5 = Data(cardNumber.utf8);
|
||||
testReceiver2(hasher: Insecure.MD5.self, value: value5);
|
||||
|
||||
let value6 = Data(cardNumber.utf8);
|
||||
@@ -248,11 +248,11 @@ func testWithFlowAndMetatypes(cardNumber: String) {
|
||||
}
|
||||
|
||||
func testReceiver1(value: Data) {
|
||||
let _digest = Insecure.MD5.hash(data: value); // $ Alert
|
||||
let _digest = Insecure.MD5.hash(data: value); // BAD
|
||||
}
|
||||
|
||||
func testReceiver2(hasher: Insecure.MD5.Type, value: Data) {
|
||||
let _digest = hasher.hash(data: value); // $ Alert
|
||||
let _digest = hasher.hash(data: value); // BAD
|
||||
}
|
||||
|
||||
func testReceiver3<H: HashFunction>(hasher: H.Type, value: Data) {
|
||||
|
||||
@@ -150,83 +150,83 @@ extension String {
|
||||
|
||||
func testArrays(harmlessArray: Array<UInt8>, phoneNumberArray: Array<UInt8>, passwdArray: Array<UInt8>) {
|
||||
_ = MD5().calculate(for: harmlessArray) // GOOD (not sensitive)
|
||||
_ = MD5().calculate(for: phoneNumberArray) // $ Alert
|
||||
_ = MD5().calculate(for: passwdArray) // $ Alert
|
||||
_ = MD5().calculate(for: phoneNumberArray) // BAD
|
||||
_ = MD5().calculate(for: passwdArray) // BAD
|
||||
_ = SHA1().calculate(for: harmlessArray) // GOOD (not sensitive)
|
||||
_ = SHA1().calculate(for: phoneNumberArray) // $ Alert
|
||||
_ = SHA1().calculate(for: passwdArray) // $ Alert
|
||||
_ = SHA1().calculate(for: phoneNumberArray) // BAD
|
||||
_ = SHA1().calculate(for: passwdArray) // BAD
|
||||
_ = SHA2(variant: .sha512).calculate(for: harmlessArray) // GOOD
|
||||
_ = SHA2(variant: .sha512).calculate(for: phoneNumberArray) // GOOD
|
||||
_ = SHA2(variant: .sha512).calculate(for: passwdArray) // $ Alert
|
||||
_ = SHA2(variant: .sha512).calculate(for: passwdArray) // BAD
|
||||
_ = SHA3(variant: .sha512).calculate(for: harmlessArray) // GOOD
|
||||
_ = SHA3(variant: .sha512).calculate(for: phoneNumberArray) // GOOD
|
||||
_ = SHA3(variant: .sha512).calculate(for: passwdArray) // $ Alert
|
||||
_ = SHA3(variant: .sha512).calculate(for: passwdArray) // BAD
|
||||
|
||||
_ = Digest.md5(harmlessArray) // GOOD (not sensitive)
|
||||
_ = Digest.md5(phoneNumberArray) // $ Alert
|
||||
_ = Digest.md5(passwdArray) // $ Alert
|
||||
_ = Digest.md5(phoneNumberArray) // BAD
|
||||
_ = Digest.md5(passwdArray) // BAD
|
||||
_ = Digest.sha1(harmlessArray) // GOOD (not sensitive)
|
||||
_ = Digest.sha1(phoneNumberArray) // $ Alert
|
||||
_ = Digest.sha1(passwdArray) // $ Alert
|
||||
_ = Digest.sha1(phoneNumberArray) // BAD
|
||||
_ = Digest.sha1(passwdArray) // BAD
|
||||
_ = Digest.sha512(harmlessArray) // GOOD (not sensitive)
|
||||
_ = Digest.sha512(phoneNumberArray) // GOOD
|
||||
_ = Digest.sha512(passwdArray) // $ Alert
|
||||
_ = Digest.sha512(passwdArray) // BAD
|
||||
_ = Digest.sha2(harmlessArray, variant: .sha512) // GOOD (not sensitive)
|
||||
_ = Digest.sha2(phoneNumberArray, variant: .sha512) // GOOD
|
||||
_ = Digest.sha2(passwdArray, variant: .sha512) // $ Alert
|
||||
_ = Digest.sha2(passwdArray, variant: .sha512) // BAD
|
||||
_ = Digest.sha3(harmlessArray, variant: .sha512) // GOOD (not sensitive)
|
||||
_ = Digest.sha3(phoneNumberArray, variant: .sha512) // GOOD
|
||||
_ = Digest.sha3(passwdArray, variant: .sha512) // $ Alert
|
||||
_ = Digest.sha3(passwdArray, variant: .sha512) // BAD
|
||||
|
||||
_ = harmlessArray.md5() // GOOD (not sensitive)
|
||||
_ = phoneNumberArray.md5() // $ Alert
|
||||
_ = passwdArray.md5() // $ Alert
|
||||
_ = phoneNumberArray.md5() // BAD
|
||||
_ = passwdArray.md5() // BAD
|
||||
_ = harmlessArray.sha1() // GOOD (not sensitive)
|
||||
_ = phoneNumberArray.sha1() // $ Alert
|
||||
_ = passwdArray.sha1() // $ Alert
|
||||
_ = phoneNumberArray.sha1() // BAD
|
||||
_ = passwdArray.sha1() // BAD
|
||||
_ = harmlessArray.sha512() // GOOD
|
||||
_ = phoneNumberArray.sha512() // GOOD
|
||||
_ = passwdArray.sha512() // $ Alert
|
||||
_ = passwdArray.sha512() // BAD
|
||||
_ = harmlessArray.sha2(.sha512) // GOOD
|
||||
_ = phoneNumberArray.sha2(.sha512) // GOOD
|
||||
_ = passwdArray.sha2(.sha512) // $ Alert
|
||||
_ = passwdArray.sha2(.sha512) // BAD
|
||||
_ = harmlessArray.sha3(.sha512) // GOOD
|
||||
_ = phoneNumberArray.sha3(.sha512) // GOOD
|
||||
_ = passwdArray.sha3(.sha512) // $ Alert
|
||||
_ = passwdArray.sha3(.sha512) // BAD
|
||||
}
|
||||
|
||||
func testData(harmlessData: Data, medicalData: Data, passwdData: Data) {
|
||||
_ = harmlessData.md5() // GOOD (not sensitive)
|
||||
_ = medicalData.md5() // $ Alert
|
||||
_ = passwdData.md5() // $ Alert
|
||||
_ = medicalData.md5() // BAD
|
||||
_ = passwdData.md5() // BAD
|
||||
_ = harmlessData.sha1() // GOOD (not sensitive)
|
||||
_ = medicalData.sha1() // $ Alert
|
||||
_ = passwdData.sha1() // $ Alert
|
||||
_ = medicalData.sha1() // BAD
|
||||
_ = passwdData.sha1() // BAD
|
||||
_ = harmlessData.sha512() // GOOD
|
||||
_ = medicalData.sha512() // GOOD
|
||||
_ = passwdData.sha512() // $ Alert
|
||||
_ = passwdData.sha512() // BAD
|
||||
_ = harmlessData.sha2(.sha512) // GOOD
|
||||
_ = medicalData.sha2(.sha512) // GOOD
|
||||
_ = passwdData.sha2(.sha512) // $ Alert
|
||||
_ = passwdData.sha2(.sha512) // BAD
|
||||
_ = harmlessData.sha3(.sha512) // GOOD
|
||||
_ = medicalData.sha3(.sha512) // GOOD
|
||||
_ = passwdData.sha3(.sha512) // $ Alert
|
||||
_ = passwdData.sha3(.sha512) // BAD
|
||||
}
|
||||
|
||||
func testStrings(creditCardNumber: String, passwd: String) {
|
||||
_ = "harmless".md5() // GOOD (not sensitive)
|
||||
_ = creditCardNumber.md5() // $ Alert
|
||||
_ = passwd.md5() // $ Alert
|
||||
_ = creditCardNumber.md5() // BAD
|
||||
_ = passwd.md5() // BAD
|
||||
_ = "harmless".sha1() // GOOD (not sensitive)
|
||||
_ = creditCardNumber.sha1() // $ Alert
|
||||
_ = passwd.sha1() // $ Alert
|
||||
_ = creditCardNumber.sha1() // BAD
|
||||
_ = passwd.sha1() // BAD
|
||||
_ = "harmless".sha512() // GOOD
|
||||
_ = creditCardNumber.sha512() // GOOD
|
||||
_ = passwd.sha512() // $ Alert
|
||||
_ = passwd.sha512() // BAD
|
||||
_ = "harmless".sha2(.sha512) // GOOD
|
||||
_ = creditCardNumber.sha2(.sha512) // GOOD
|
||||
_ = passwd.sha2(.sha512) // $ Alert
|
||||
_ = passwd.sha2(.sha512) // BAD
|
||||
_ = "harmless".sha3(.sha512) // GOOD
|
||||
_ = creditCardNumber.sha3(.sha512) // GOOD
|
||||
_ = passwd.sha3(.sha512) // $ Alert
|
||||
_ = passwd.sha3(.sha512) // BAD
|
||||
}
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
query: queries/Security/CWE-730/RegexInjection.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
queries/Security/CWE-730/RegexInjection.ql
|
||||
|
||||
@@ -92,59 +92,59 @@ extension String {
|
||||
|
||||
func regexInjectionTests(cond: Bool, varString: String, myUrl: URL) throws {
|
||||
let constString = ".*"
|
||||
let taintedString = String(contentsOf: myUrl) // $ Source // tainted
|
||||
let taintedString = String(contentsOf: myUrl) // tainted
|
||||
|
||||
// --- Regex ---
|
||||
|
||||
_ = try Regex(constString).firstMatch(in: varString)
|
||||
_ = try Regex(varString).firstMatch(in: varString)
|
||||
_ = try Regex(taintedString).firstMatch(in: varString) // $ Alert
|
||||
_ = try Regex(taintedString).firstMatch(in: varString) // BAD
|
||||
|
||||
_ = try Regex("(a|" + constString + ")").firstMatch(in: varString)
|
||||
_ = try Regex("(a|" + taintedString + ")").firstMatch(in: varString) // $ Alert
|
||||
_ = try Regex("(a|" + taintedString + ")").firstMatch(in: varString) // BAD
|
||||
_ = try Regex("(a|\(constString))").firstMatch(in: varString)
|
||||
_ = try Regex("(a|\(taintedString))").firstMatch(in: varString) // $ Alert
|
||||
_ = try Regex("(a|\(taintedString))").firstMatch(in: varString) // BAD
|
||||
|
||||
_ = try Regex(cond ? constString : constString).firstMatch(in: varString)
|
||||
_ = try Regex(cond ? taintedString : constString).firstMatch(in: varString) // $ Alert
|
||||
_ = try Regex(cond ? constString : taintedString).firstMatch(in: varString) // $ Alert
|
||||
_ = try Regex(cond ? taintedString : constString).firstMatch(in: varString) // BAD
|
||||
_ = try Regex(cond ? constString : taintedString).firstMatch(in: varString) // BAD
|
||||
|
||||
_ = try (cond ? Regex(constString) : Regex(constString)).firstMatch(in: varString)
|
||||
_ = try (cond ? Regex(taintedString) : Regex(constString)).firstMatch(in: varString) // $ Alert
|
||||
_ = try (cond ? Regex(constString) : Regex(taintedString)).firstMatch(in: varString) // $ Alert
|
||||
_ = try (cond ? Regex(taintedString) : Regex(constString)).firstMatch(in: varString) // BAD
|
||||
_ = try (cond ? Regex(constString) : Regex(taintedString)).firstMatch(in: varString) // BAD
|
||||
|
||||
// --- RangeReplaceableCollection ---
|
||||
|
||||
var inputVar = varString
|
||||
inputVar.replace(constString, with: "")
|
||||
inputVar.replace(taintedString, with: "") // $ Alert
|
||||
inputVar.replace(taintedString, with: "") // BAD
|
||||
inputVar.replace(constString, with: taintedString)
|
||||
|
||||
// --- StringProtocol ---
|
||||
|
||||
_ = inputVar.replacingOccurrences(of: constString, with: "", options: .regularExpression)
|
||||
_ = inputVar.replacingOccurrences(of: taintedString, with: "", options: .regularExpression) // $ Alert
|
||||
_ = inputVar.replacingOccurrences(of: taintedString, with: "", options: .regularExpression) // BAD
|
||||
|
||||
// --- NSRegularExpression ---
|
||||
|
||||
_ = try NSRegularExpression(pattern: constString).firstMatch(in: varString, range: NSMakeRange(0, varString.utf16.count))
|
||||
_ = try NSRegularExpression(pattern: taintedString).firstMatch(in: varString, range: NSMakeRange(0, varString.utf16.count)) // $ Alert
|
||||
_ = try NSRegularExpression(pattern: taintedString).firstMatch(in: varString, range: NSMakeRange(0, varString.utf16.count)) // BAD
|
||||
|
||||
// --- NSString ---
|
||||
|
||||
let nsString = NSString(string: varString)
|
||||
_ = nsString.replacingOccurrences(of: constString, with: "", options: .regularExpression, range: NSMakeRange(0, nsString.length))
|
||||
_ = nsString.replacingOccurrences(of: taintedString, with: "", options: .regularExpression, range: NSMakeRange(0, nsString.length)) // $ Alert
|
||||
_ = nsString.replacingOccurrences(of: taintedString, with: "", options: .regularExpression, range: NSMakeRange(0, nsString.length)) // BAD
|
||||
|
||||
// --- from the qhelp ---
|
||||
|
||||
let remoteInput = taintedString
|
||||
let myRegex = ".*"
|
||||
|
||||
_ = try Regex(remoteInput) // $ Alert
|
||||
_ = try Regex(remoteInput) // BAD
|
||||
|
||||
let regexStr = "abc|\(remoteInput)"
|
||||
_ = try NSRegularExpression(pattern: regexStr) // $ Alert
|
||||
_ = try NSRegularExpression(pattern: regexStr) // BAD
|
||||
|
||||
_ = try Regex(myRegex)
|
||||
|
||||
@@ -159,35 +159,35 @@ func regexInjectionTests(cond: Bool, varString: String, myUrl: URL) throws {
|
||||
let okSet: Set = ["abc", "def"]
|
||||
|
||||
if (taintedString == okInput) {
|
||||
_ = try Regex(taintedString).firstMatch(in: varString) // $ Alert // GOOD (effectively sanitized by the check) [FALSE POSITIVE]
|
||||
_ = try Regex(taintedString).firstMatch(in: varString) // GOOD (effectively sanitized by the check) [FALSE POSITIVE]
|
||||
} else {
|
||||
_ = try Regex(taintedString).firstMatch(in: varString) // $ Alert
|
||||
_ = try Regex(taintedString).firstMatch(in: varString) // BAD
|
||||
}
|
||||
if (taintedString != okInput) {
|
||||
_ = try Regex(taintedString).firstMatch(in: varString) // $ Alert
|
||||
_ = try Regex(taintedString).firstMatch(in: varString) // BAD
|
||||
}
|
||||
if (varString == okInput) {
|
||||
_ = try Regex(taintedString).firstMatch(in: varString) // $ Alert
|
||||
_ = try Regex(taintedString).firstMatch(in: varString) // BAD
|
||||
}
|
||||
if (okInputs.contains(taintedString)) {
|
||||
_ = try Regex(taintedString).firstMatch(in: varString) // $ Alert // GOOD (effectively sanitized by the check) [FALSE POSITIVE]
|
||||
_ = try Regex(taintedString).firstMatch(in: varString) // GOOD (effectively sanitized by the check) [FALSE POSITIVE]
|
||||
}
|
||||
if (okInputs.firstIndex(of: taintedString) != nil) {
|
||||
_ = try Regex(taintedString).firstMatch(in: varString) // $ Alert // GOOD (effectively sanitized by the check) [FALSE POSITIVE]
|
||||
_ = try Regex(taintedString).firstMatch(in: varString) // GOOD (effectively sanitized by the check) [FALSE POSITIVE]
|
||||
}
|
||||
if let index = okInputs.firstIndex(of: taintedString) {
|
||||
_ = try Regex(taintedString).firstMatch(in: varString) // $ Alert // GOOD (effectively sanitized by the check) [FALSE POSITIVE]
|
||||
_ = try Regex(taintedString).firstMatch(in: varString) // GOOD (effectively sanitized by the check) [FALSE POSITIVE]
|
||||
}
|
||||
if let index = okInputs.index(of: taintedString) {
|
||||
_ = try Regex(taintedString).firstMatch(in: varString) // $ Alert // GOOD (effectively sanitized by the check) [FALSE POSITIVE]
|
||||
_ = try Regex(taintedString).firstMatch(in: varString) // GOOD (effectively sanitized by the check) [FALSE POSITIVE]
|
||||
}
|
||||
if (okSet.contains(taintedString)) {
|
||||
_ = try Regex(taintedString).firstMatch(in: varString) // $ Alert // GOOD (effectively sanitized by the check) [FALSE POSITIVE]
|
||||
_ = try Regex(taintedString).firstMatch(in: varString) // GOOD (effectively sanitized by the check) [FALSE POSITIVE]
|
||||
}
|
||||
|
||||
// --- multiple evaluations ---
|
||||
|
||||
let re = try Regex(taintedString) // $ Alert
|
||||
let re = try Regex(taintedString) // BAD
|
||||
_ = try re.firstMatch(in: varString) // (we only want to flag one location total)
|
||||
_ = try re.firstMatch(in: varString)
|
||||
}
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
query: queries/Security/CWE-760/ConstantSalt.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
queries/Security/CWE-760/ConstantSalt.ql
|
||||
|
||||
@@ -56,27 +56,27 @@ func test(myPassword: String) {
|
||||
let myIV = Data(0)
|
||||
let myRandomSalt1 = Data(getARandomString())
|
||||
let myRandomSalt2 = Data(getARandomString())
|
||||
let myConstantSalt1 = Data("abcdef123456") // $ Source
|
||||
let myConstantSalt2 = Data(0) // $ Source
|
||||
let myConstantSalt1 = Data("abcdef123456")
|
||||
let myConstantSalt2 = Data(0)
|
||||
|
||||
let _ = myEncryptor.key(forPassword: myPassword, salt: myRandomSalt1, settings: myKeyDerivationSettings) // GOOD
|
||||
let _ = myEncryptor.key(forPassword: myPassword, salt: myConstantSalt1, settings: myKeyDerivationSettings) // $ Alert
|
||||
let _ = myEncryptor.key(forPassword: myPassword, salt: myConstantSalt1, settings: myKeyDerivationSettings) // BAD
|
||||
let _ = myEncryptor.keyForPassword(myPassword, salt: myRandomSalt2, settings: myKeyDerivationSettings) // GOOD
|
||||
let _ = myEncryptor.keyForPassword(myPassword, salt: myConstantSalt2, settings: myKeyDerivationSettings) // $ Alert
|
||||
let _ = myEncryptor.keyForPassword(myPassword, salt: myConstantSalt2, settings: myKeyDerivationSettings) // BAD
|
||||
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, iv: myIV, encryptionSalt: myRandomSalt1, hmacSalt: myRandomSalt2, handler: myHandler) // GOOD
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, iv: myIV, encryptionSalt: myConstantSalt1, hmacSalt: myRandomSalt2, handler: myHandler) // $ Alert
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, iv: myIV, encryptionSalt: myRandomSalt1, hmacSalt: myConstantSalt2, handler: myHandler) // $ Alert
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, iv: myIV, encryptionSalt: myConstantSalt1, hmacSalt: myRandomSalt2, handler: myHandler) // BAD
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, iv: myIV, encryptionSalt: myRandomSalt1, hmacSalt: myConstantSalt2, handler: myHandler) // BAD
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, IV: myIV, encryptionSalt: myRandomSalt1, HMACSalt: myRandomSalt2, handler: myHandler) // GOOD
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, IV: myIV, encryptionSalt: myConstantSalt1, HMACSalt: myRandomSalt2, handler: myHandler) // $ Alert
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, IV: myIV, encryptionSalt: myRandomSalt1, HMACSalt: myConstantSalt2, handler: myHandler) // $ Alert
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, IV: myIV, encryptionSalt: myConstantSalt1, HMACSalt: myRandomSalt2, handler: myHandler) // BAD
|
||||
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, IV: myIV, encryptionSalt: myRandomSalt1, HMACSalt: myConstantSalt2, handler: myHandler) // BAD
|
||||
|
||||
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myPassword, iv: myIV, encryptionSalt: myRandomSalt1, hmacSalt: myRandomSalt2) // GOOD
|
||||
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myPassword, iv: myIV, encryptionSalt: myConstantSalt1, hmacSalt: myRandomSalt2) // $ Alert
|
||||
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myPassword, iv: myIV, encryptionSalt: myRandomSalt1, hmacSalt: myConstantSalt2) // $ Alert
|
||||
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myPassword, iv: myIV, encryptionSalt: myConstantSalt1, hmacSalt: myRandomSalt2) // BAD
|
||||
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myPassword, iv: myIV, encryptionSalt: myRandomSalt1, hmacSalt: myConstantSalt2) // BAD
|
||||
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, password: myPassword, IV: myIV, encryptionSalt: myRandomSalt1, HMACSalt: myRandomSalt2) // GOOD
|
||||
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, password: myPassword, IV: myIV, encryptionSalt: myConstantSalt1, HMACSalt: myRandomSalt2) // $ Alert
|
||||
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, password: myPassword, IV: myIV, encryptionSalt: myRandomSalt1, HMACSalt: myConstantSalt2) // $ Alert
|
||||
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, password: myPassword, IV: myIV, encryptionSalt: myConstantSalt1, HMACSalt: myRandomSalt2) // BAD
|
||||
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, password: myPassword, IV: myIV, encryptionSalt: myRandomSalt1, HMACSalt: myConstantSalt2) // BAD
|
||||
|
||||
// appending constants
|
||||
let _ = myEncryptor.key(forPassword: myPassword, salt: Data(getARandomString() + getARandomString()), settings: myKeyDerivationSettings) // GOOD
|
||||
|
||||
@@ -26,7 +26,7 @@ final class Scrypt {
|
||||
|
||||
// Helper functions
|
||||
func getConstantString() -> String {
|
||||
"this string is constant" // $ Source
|
||||
"this string is constant"
|
||||
}
|
||||
|
||||
func getConstantArray() -> Array<UInt8> {
|
||||
@@ -40,7 +40,7 @@ func getRandomArray() -> Array<UInt8> {
|
||||
// --- tests ---
|
||||
|
||||
func test() {
|
||||
let constantSalt: Array<UInt8> = [0x2a, 0x3a, 0x80, 0x05, 0xaf, 0x46, 0x58, 0x2d, 0x66, 0x52, 0x10, 0xae, 0x86, 0xd3, 0x8e, 0x8f] // $ Source
|
||||
let constantSalt: Array<UInt8> = [0x2a, 0x3a, 0x80, 0x05, 0xaf, 0x46, 0x58, 0x2d, 0x66, 0x52, 0x10, 0xae, 0x86, 0xd3, 0x8e, 0x8f]
|
||||
let constantStringSalt = getConstantArray()
|
||||
let randomSalt = getRandomArray()
|
||||
let randomArray = getRandomArray()
|
||||
@@ -48,23 +48,23 @@ func test() {
|
||||
let iterations = 120120
|
||||
|
||||
// HKDF test cases
|
||||
let hkdfb1 = HKDF(password: randomArray, salt: constantSalt, info: randomArray, keyLength: 0, variant: variant) // $ Alert
|
||||
let hkdfb2 = HKDF(password: randomArray, salt: constantStringSalt, info: randomArray, keyLength: 0, variant: variant) // $ Alert
|
||||
let hkdfb1 = HKDF(password: randomArray, salt: constantSalt, info: randomArray, keyLength: 0, variant: variant) // BAD
|
||||
let hkdfb2 = HKDF(password: randomArray, salt: constantStringSalt, info: randomArray, keyLength: 0, variant: variant) // BAD
|
||||
let hkdfg1 = HKDF(password: randomArray, salt: randomSalt, info: randomArray, keyLength: 0, variant: variant) // GOOD
|
||||
|
||||
// PBKDF1 test cases
|
||||
let pbkdf1b1 = PKCS5.PBKDF1(password: randomArray, salt: constantSalt, iterations: iterations, keyLength: 0) // $ Alert
|
||||
let pbkdf1b2 = PKCS5.PBKDF1(password: randomArray, salt: constantStringSalt, iterations: iterations, keyLength: 0) // $ Alert
|
||||
let pbkdf1b1 = PKCS5.PBKDF1(password: randomArray, salt: constantSalt, iterations: iterations, keyLength: 0) // BAD
|
||||
let pbkdf1b2 = PKCS5.PBKDF1(password: randomArray, salt: constantStringSalt, iterations: iterations, keyLength: 0) // BAD
|
||||
let pbkdf1g1 = PKCS5.PBKDF1(password: randomArray, salt: randomSalt, iterations: iterations, keyLength: 0) // GOOD
|
||||
|
||||
|
||||
// PBKDF2 test cases
|
||||
let pbkdf2b1 = PKCS5.PBKDF2(password: randomArray, salt: constantSalt, iterations: iterations, keyLength: 0) // $ Alert
|
||||
let pbkdf2b2 = PKCS5.PBKDF2(password: randomArray, salt: constantStringSalt, iterations: iterations, keyLength: 0) // $ Alert
|
||||
let pbkdf2b1 = PKCS5.PBKDF2(password: randomArray, salt: constantSalt, iterations: iterations, keyLength: 0) // BAD
|
||||
let pbkdf2b2 = PKCS5.PBKDF2(password: randomArray, salt: constantStringSalt, iterations: iterations, keyLength: 0) // BAD
|
||||
let pbkdf2g1 = PKCS5.PBKDF2(password: randomArray, salt: randomSalt, iterations: iterations, keyLength: 0) // GOOD
|
||||
|
||||
// Scrypt test cases
|
||||
let scryptb1 = Scrypt(password: randomArray, salt: constantSalt, dkLen: 64, N: 16384, r: 8, p: 1) // $ Alert
|
||||
let scryptb2 = Scrypt(password: randomArray, salt: constantStringSalt, dkLen: 64, N: 16384, r: 8, p: 1) // $ Alert
|
||||
let scryptb1 = Scrypt(password: randomArray, salt: constantSalt, dkLen: 64, N: 16384, r: 8, p: 1) // BAD
|
||||
let scryptb2 = Scrypt(password: randomArray, salt: constantStringSalt, dkLen: 64, N: 16384, r: 8, p: 1) // BAD
|
||||
let scryptg1 = Scrypt(password: randomArray, salt: randomSalt, dkLen: 64, N: 16384, r: 8, p: 1) // GOOD
|
||||
}
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
query: queries/Security/CWE-916/InsufficientHashIterations.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
queries/Security/CWE-916/InsufficientHashIterations.ql
|
||||
|
||||
@@ -17,7 +17,7 @@ extension PKCS5 {
|
||||
}
|
||||
|
||||
// Helper functions
|
||||
func getLowIterationCount() -> Int { return 99999 } // $ Source
|
||||
func getLowIterationCount() -> Int { return 99999 }
|
||||
|
||||
func getEnoughIterationCount() -> Int { return 120120 }
|
||||
|
||||
@@ -34,15 +34,15 @@ func test() {
|
||||
let enoughIterations = getEnoughIterationCount()
|
||||
|
||||
// PBKDF1 test cases
|
||||
let pbkdf1b1 = PKCS5.PBKDF1(password: randomArray, salt: randomArray, iterations: lowIterations, keyLength: 0) // $ Alert
|
||||
let pbkdf1b2 = PKCS5.PBKDF1(password: randomArray, salt: randomArray, iterations: 80000, keyLength: 0) // $ Alert
|
||||
let pbkdf1b1 = PKCS5.PBKDF1(password: randomArray, salt: randomArray, iterations: lowIterations, keyLength: 0) // BAD
|
||||
let pbkdf1b2 = PKCS5.PBKDF1(password: randomArray, salt: randomArray, iterations: 80000, keyLength: 0) // BAD
|
||||
let pbkdf1g1 = PKCS5.PBKDF1(password: randomArray, salt: randomArray, iterations: enoughIterations, keyLength: 0) // GOOD
|
||||
let pbkdf1g2 = PKCS5.PBKDF1(password: randomArray, salt: randomArray, iterations: 120120, keyLength: 0) // GOOD
|
||||
|
||||
|
||||
// PBKDF2 test cases
|
||||
let pbkdf2b1 = PKCS5.PBKDF2(password: randomArray, salt: randomArray, iterations: lowIterations, keyLength: 0) // $ Alert
|
||||
let pbkdf2b2 = PKCS5.PBKDF2(password: randomArray, salt: randomArray, iterations: 80000, keyLength: 0) // $ Alert
|
||||
let pbkdf2b1 = PKCS5.PBKDF2(password: randomArray, salt: randomArray, iterations: lowIterations, keyLength: 0) // BAD
|
||||
let pbkdf2b2 = PKCS5.PBKDF2(password: randomArray, salt: randomArray, iterations: 80000, keyLength: 0) // BAD
|
||||
let pbkdf2g1 = PKCS5.PBKDF2(password: randomArray, salt: randomArray, iterations: enoughIterations, keyLength: 0) // GOOD
|
||||
let pbkdf2g2 = PKCS5.PBKDF2(password: randomArray, salt: randomArray, iterations: 120120, keyLength: 0) // GOOD
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user