Compare commits

..

9 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
d73a911d74 Convert Swift .qlref tests to inline expectation tests 2026-06-11 22:48:07 +00:00
copilot-swe-agent[bot]
de8b3360bc Initial plan 2026-06-11 22:22:11 +00:00
Asger F
ad18659373 Merge pull request #21796 from mattcosta7/patch-1
Add UseMemoDirective and UseNoMemoDirective classes
2026-06-11 23:01:29 +02:00
Matthew Costabile
923fe2dcb9 Merge branch 'main' into patch-1 2026-06-11 15:19:58 -04:00
Matthew Costabile
2884428b62 Merge branch 'main' into patch-1 2026-05-26 07:16:24 -04:00
Matthew Costabile
e10750b35e Merge branch 'main' into patch-1 2026-05-05 22:09:09 -04:00
Matthew Costabile
18550039f2 Update KnownDirective.expected 2026-05-05 11:06:40 -04:00
Matthew Costabile
0caa483925 change note and test 2026-05-05 13:20:39 +00:00
Matthew Costabile
640b17ec78 Add UseMemoDirective and UseNoMemoDirective classes 2026-05-05 07:41:36 -04:00
64 changed files with 807 additions and 750 deletions

View File

@@ -2,7 +2,7 @@
### Minor Analysis Improvements
* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, including regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a SHA-1 or SHA-256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used.
* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, include regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a sha1 or sha256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used.
## 0.4.36

View File

@@ -2,4 +2,4 @@
### Minor Analysis Improvements
* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, including regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a SHA-1 or SHA-256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used.
* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, include regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a sha1 or sha256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used.

View File

@@ -15,7 +15,7 @@
### Bug Fixes
* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on a minor point, added one more listed resource and added one more recommendation for things to check.
* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on in minor point, added one more listed resource and added one more recommendation for things to check.
## 0.6.28

View File

@@ -15,4 +15,4 @@
### Bug Fixes
* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on a minor point, added one more listed resource and added one more recommendation for things to check.
* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on in minor point, added one more listed resource and added one more recommendation for things to check.

View File

@@ -0,0 +1,4 @@
---
category: feature
---
* Added `UseMemoDirective` and `UseNoMemoDirective` classes to model the React compiler directives `"use memo"` and `"use no memo"`.

View File

@@ -435,6 +435,32 @@ module Directive {
UseClientDirective() { this.getDirectiveText() = "use client" }
}
/**
* A `use memo` directive.
*
* Example:
*
* ```
* "use memo";
* ```
*/
class UseMemoDirective extends KnownDirective {
UseMemoDirective() { this.getDirectiveText() = "use memo" }
}
/**
* A `use no memo` directive.
*
* Example:
*
* ```
* "use no memo";
* ```
*/
class UseNoMemoDirective extends KnownDirective {
UseNoMemoDirective() { this.getDirectiveText() = "use no memo" }
}
/**
* A `use cache` directive.
*

View File

@@ -3,14 +3,18 @@
| tst.js:3:1:3:9 | 'bundle'; | bundle |
| tst.js:4:1:4:13 | 'use server'; | use server |
| tst.js:5:1:5:13 | 'use client'; | use client |
| tst.js:6:1:6:12 | 'use cache'; | use cache |
| tst.js:7:1:7:20 | 'use cache: remote'; | use cache: remote |
| tst.js:8:1:8:21 | 'use ca ... ivate'; | use cache: private |
| tst.js:17:3:17:12 | 'use asm'; | use asm |
| tst.js:18:3:18:11 | 'bundle'; | bundle |
| tst.js:19:3:19:15 | 'use server'; | use server |
| tst.js:20:3:20:15 | 'use client'; | use client |
| tst.js:21:3:21:14 | 'use cache'; | use cache |
| tst.js:22:3:22:22 | 'use cache: remote'; | use cache: remote |
| tst.js:23:3:23:23 | 'use ca ... ivate'; | use cache: private |
| tst.js:30:5:30:17 | 'use strict'; | use strict |
| tst.js:6:1:6:11 | 'use memo'; | use memo |
| tst.js:7:1:7:14 | 'use no memo'; | use no memo |
| tst.js:8:1:8:12 | 'use cache'; | use cache |
| tst.js:9:1:9:20 | 'use cache: remote'; | use cache: remote |
| tst.js:10:1:10:21 | 'use ca ... ivate'; | use cache: private |
| tst.js:19:3:19:12 | 'use asm'; | use asm |
| tst.js:20:3:20:11 | 'bundle'; | bundle |
| tst.js:21:3:21:15 | 'use server'; | use server |
| tst.js:22:3:22:15 | 'use client'; | use client |
| tst.js:23:3:23:13 | 'use memo'; | use memo |
| tst.js:24:3:24:16 | 'use no memo'; | use no memo |
| tst.js:25:3:25:14 | 'use cache'; | use cache |
| tst.js:26:3:26:22 | 'use cache: remote'; | use cache: remote |
| tst.js:27:3:27:23 | 'use ca ... ivate'; | use cache: private |
| tst.js:34:5:34:17 | 'use strict'; | use strict |

View File

@@ -3,6 +3,8 @@
'bundle';// and this
'use server';
'use client';
'use memo';
'use no memo';
'use cache';
'use cache: remote';
'use cache: private';
@@ -18,6 +20,8 @@ function f() {
'bundle';
'use server';
'use client';
'use memo';
'use no memo';
'use cache';
'use cache: remote';
'use cache: private';

View File

@@ -2,7 +2,7 @@
### Minor Analysis Improvements
* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `py/clear-text-logging-sensitive-data`) may find more correct results and fewer false positive results after these changes.
* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `py/clear-text-logging-sensitive-data`) may find more correct results and less fewer positive results after these changes.
## 7.1.1

View File

@@ -2,4 +2,4 @@
### Minor Analysis Improvements
* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `py/clear-text-logging-sensitive-data`) may find more correct results and fewer false positive results after these changes.
* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `py/clear-text-logging-sensitive-data`) may find more correct results and less fewer positive results after these changes.

View File

@@ -1 +1,2 @@
queries/Security/CWE-020/IncompleteHostnameRegex.ql
query: queries/Security/CWE-020/IncompleteHostnameRegex.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1,2 @@
queries/Security/CWE-020/MissingRegexAnchor.ql
query: queries/Security/CWE-020/MissingRegexAnchor.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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) // BAD (missing anchor)
_ = try Regex("^a|b").firstMatch(in: input) // $ Alert // 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) // BAD (missing anchor)
_ = try Regex("^a|b|c").firstMatch(in: input) // $ Alert // 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) // BAD (missing anchor)
_ = try Regex("^a|(b)").firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex("^a|(^b)").firstMatch(in: input)
_ = 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) // $ Alert // 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) // BAD (missing anchor)
_ = try Regex("a|b|c$").firstMatch(in: input) // $ Alert // 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) // BAD (missing anchor)
_ = try Regex("(a)|b$").firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex("(a$)|b$").firstMatch(in: input)
_ = try Regex("(a)|(b)$").firstMatch(in: input) // BAD (missing anchor)
_ = try Regex("(a)|(b)$").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(#"^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("^foo|bar|baz$").firstMatch(in: input) // BAD (missing anchor)
_ = try Regex("^foo|bar|baz$").firstMatch(in: input) // $ Alert // 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) // 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(#"(\.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(#"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

View File

@@ -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) // 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) // $ 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) // $ Alert // BAD (missing anchor)
_ = try NSRegularExpression(pattern: "https?://good.com").matches(in: input, range: inputRange) // $ Alert // BAD (missing anchor)
if let _ = try NSRegularExpression(pattern: "https?://good.com").firstMatch(in: input, range: inputRange) { } // BAD (missing anchor)
if let _ = try NSRegularExpression(pattern: "https?://good.com").firstMatch(in: input, range: inputRange) { } // $ Alert // 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) // BAD (missing anchor)
_ = try NSRegularExpression(pattern: #"https?://good.com:8080"#).firstMatch(in: input, range: inputRange) // BAD (missing anchor)
_ = 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)
let trustedUrlRegexs = [
"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
"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
]
for trustedUrlRegex in trustedUrlRegexs {
if let _ = try NSRegularExpression(pattern: trustedUrlRegex).firstMatch(in: input, range: inputRange) { }
}
let trustedUrlRegexs2 = [
"https?://good.com", // BAD (missing anchor), referenced below
"https?://good.com", // $ Alert // 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) // BAD (missing anchor)
_ = try NSRegularExpression(pattern: #"https?:\/\/good.com\/([0-9]+)"#).matches(in: url, range: urlRange) // $ Alert // 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) // OK, the other disjunction doesn't match a hostname [FALSE POSITIVE]
_ = try NSRegularExpression(pattern: #"example\.com|whatever"#).matches(in: input, range: inputRange) // $ Alert // OK, the other disjunction doesn't match a hostname [FALSE POSITIVE]
// tests for the `isLineAnchoredHostnameRegExp` case

View File

@@ -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) // BAD (missing anchor)
_ = try Regex(#"^http://example.com"#).firstMatch(in: tainted) // $ Alert // 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) // BAD (missing anchor)
_ = try Regex(#"^http://test.example.com/"#).firstMatch(in: tainted) // BAD (incomplete hostname)
_ = 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) // GOOD (alternative method of escaping)
_ = 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://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://(\.+)\.example.com/"#).firstMatch(in: tainted) // GOOD
_ = 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://(?:.+)\.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[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) // 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(#"^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(#"^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) // DUBIOUS (one disjunction doesn't even look like a hostname) [DETECTED incomplete hostname, missing anchor]
_ = 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(#"^test.example.com$"#).firstMatch(in: tainted) // BAD (incomplete hostname)
_ = try Regex(#"test.example.com"#).wholeMatch(in: tainted) // BAD (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(id(id(id(#"test.example.com$"#)))).firstMatch(in: tainted) // BAD (incomplete hostname)
_ = try Regex(id(id(id(#"test.example.com$"#)))).firstMatch(in: tainted) // $ Alert // 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$"# // BAD (incomplete hostname)
domain.hostname = #"test.example.com$"# // $ Alert // 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) // BAD (incomplete hostname)
_ = try convert1(MyDomain(#"test.example.com$"#)).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
let domains = [ MyDomain(#"test.example.com$"#) ] // BAD (incomplete hostname) [NOT DETECTED]
func convert2(_ domain: MyDomain) throws -> Regex<AnyRegexOutput> {

View File

@@ -1 +1,2 @@
experimental/Security/CWE-022/UnsafeUnpack.ql
query: experimental/Security/CWE-022/UnsafeUnpack.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -59,12 +59,12 @@ func testCommandInjectionQhelpExamples() {
let source = URL(fileURLWithPath: "/sourcePath")
let destination = URL(fileURLWithPath: "/destination")
try Data(contentsOf: remoteURL, options: []).write(to: source)
try Data(contentsOf: remoteURL, options: []).write(to: source) // $ Source
do {
try Zip.unzipFile(source, destination: destination, overwrite: true, password: nil) // BAD
try Zip.unzipFile(source, destination: destination, overwrite: true, password: nil) // $ Alert
let fileManager = FileManager()
try fileManager.unzipItem(at: source, to: destination) // BAD
try fileManager.unzipItem(at: source, to: destination) // $ Alert
} catch {
print("Error: \(error)")
}

View File

@@ -1 +1,2 @@
queries/Security/CWE-079/UnsafeWebViewFetch.ql
query: queries/Security/CWE-079/UnsafeWebViewFetch.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -91,7 +91,7 @@ func getRemoteData() -> String {
let url = URL(string: "http://example.com/")
do
{
return try String(contentsOf: url!)
return try String(contentsOf: url!) // $ Source
} 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) // BAD
webview.loadHTMLString(try! String(contentsOf: URL(string: "http://example.com/")!), baseURL: nil) // $ Alert
let data = try! String(contentsOf: URL(string: "http://example.com/")!)
webview.loadHTMLString(data, baseURL: nil) // BAD
let data = try! String(contentsOf: URL(string: "http://example.com/")!) // $ Source
webview.loadHTMLString(data, baseURL: nil) // $ Alert
let url = URL(string: "http://example.com/")
webview.loadHTMLString(try! String(contentsOf: url!), baseURL: nil) // BAD
webview.loadHTMLString(try! String(contentsOf: url!), baseURL: nil) // $ Alert
}
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) // BAD: HTML contains remote input, may access local secrets
webview.loadHTMLString(remoteString, baseURL: nil) // BAD
webview.loadHTMLString(getRemoteData(), baseURL: nil) // $ Alert // BAD: HTML contains remote input, may access local secrets
webview.loadHTMLString(remoteString, baseURL: nil) // $ Alert
webview.loadHTMLString("<html>" + localStringFragment + "</html>", baseURL: nil) // GOOD: the HTML data is local
webview.loadHTMLString("<html>" + remoteString + "</html>", baseURL: nil) // BAD
webview.loadHTMLString("<html>" + remoteString + "</html>", baseURL: nil) // $ Alert
webview.loadHTMLString("<html>\(localStringFragment)</html>", baseURL: nil) // GOOD: the HTML data is local
webview.loadHTMLString("<html>\(remoteString)</html>", baseURL: nil) // BAD
webview.loadHTMLString("<html>\(remoteString)</html>", baseURL: nil) // $ Alert
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!) // BAD
webview.loadHTMLString(remoteString, baseURL: remoteURL!) // $ Alert
webview.loadHTMLString(localString, baseURL: remoteURL2!) // GOOD: the HTML data is local
webview.loadHTMLString(remoteString, baseURL: remoteURL2!) // BAD
webview.loadHTMLString(remoteString, baseURL: remoteURL2!) // $ Alert
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!) // BAD
webview.load(remoteData, mimeType: "text/html", textEncodingName: "utf-8", baseURL: remoteURL!) // $ Alert
}
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) // BAD
webview.loadHTMLString(remoteString, baseURL: nil) // BAD
webview.loadHTMLString(getRemoteData(), baseURL: nil) // $ Alert
webview.loadHTMLString(remoteString, baseURL: nil) // $ Alert
webview.loadHTMLString("<html>" + localStringFragment + "</html>", baseURL: nil) // GOOD: the HTML data is local
webview.loadHTMLString("<html>" + remoteString + "</html>", baseURL: nil) // BAD
webview.loadHTMLString("<html>" + remoteString + "</html>", baseURL: nil) // $ Alert
webview.loadHTMLString("<html>\(localStringFragment)</html>", baseURL: nil) // GOOD: the HTML data is local
webview.loadHTMLString("<html>\(remoteString)</html>", baseURL: nil) // BAD
webview.loadHTMLString("<html>\(remoteString)</html>", baseURL: nil) // $ Alert
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!) // BAD
webview.loadHTMLString(remoteString, baseURL: remoteURL!) // $ Alert
webview.loadHTMLString(localString, baseURL: remoteURL2!) // GOOD: the HTML data is local
webview.loadHTMLString(remoteString, baseURL: remoteURL2!) // BAD
webview.loadHTMLString(remoteString, baseURL: remoteURL2!) // $ Alert
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!) // BAD
webview.load(remoteData, mimeType: "text/html", characterEncodingName: "utf-8", baseURL: remoteURL!) // $ Alert
}
func testQHelpExamples() {
@@ -207,7 +207,7 @@ func testQHelpExamples() {
// ...
webview.loadHTMLString(htmlData, baseURL: nil) // BAD
webview.loadHTMLString(htmlData, baseURL: nil) // $ Alert
webview.loadHTMLString(htmlData, baseURL: URL(string: "about:blank")) // GOOD
}

View File

@@ -101,54 +101,54 @@ class CommonTableExpression {
func test(database: Database) throws {
let localString = "user"
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
let _ = database.allStatements(sql: remoteString) // BAD
let _ = database.allStatements(sql: remoteString) // $ Alert
let _ = database.allStatements(sql: localString) // GOOD
let _ = database.allStatements(sql: remoteString, arguments: nil) // BAD
let _ = database.allStatements(sql: remoteString, arguments: nil) // $ Alert
let _ = database.allStatements(sql: localString, arguments: nil) // GOOD
let _ = database.cachedStatement(sql: remoteString) // BAD
let _ = database.cachedStatement(sql: remoteString) // $ Alert
let _ = database.cachedStatement(sql: localString) // GOOD
let _ = database.internalCachedStatement(sql: remoteString) // BAD
let _ = database.internalCachedStatement(sql: remoteString) // $ Alert
let _ = database.internalCachedStatement(sql: localString) // GOOD
database.execute(sql: remoteString) // BAD
database.execute(sql: remoteString) // $ Alert
database.execute(sql: localString) // GOOD
database.execute(sql: remoteString, arguments: StatementArguments()) // BAD
database.execute(sql: remoteString, arguments: StatementArguments()) // $ Alert
database.execute(sql: localString, arguments: StatementArguments()) // GOOD
let _ = database.makeStatement(sql: remoteString) // BAD
let _ = database.makeStatement(sql: remoteString) // $ Alert
let _ = database.makeStatement(sql: localString) // GOOD
let _ = database.makeStatement(sql: remoteString, prepFlags: 0) // BAD
let _ = database.makeStatement(sql: remoteString, prepFlags: 0) // $ Alert
let _ = database.makeStatement(sql: localString, prepFlags: 0) // GOOD
}
func testSqlRequest() throws {
let localString = "user"
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
let _ = SQLRequest(stringLiteral: remoteString) // BAD
let _ = SQLRequest(stringLiteral: remoteString) // $ Alert
let _ = SQLRequest(stringLiteral: localString) // GOOD
let _ = SQLRequest(unicodeScalarLiteral: remoteString) // BAD
let _ = SQLRequest(unicodeScalarLiteral: remoteString) // $ Alert
let _ = SQLRequest(unicodeScalarLiteral: localString) // GOOD
let _ = SQLRequest(extendedGraphemeClusterLiteral: remoteString) // BAD
let _ = SQLRequest(extendedGraphemeClusterLiteral: remoteString) // $ Alert
let _ = SQLRequest(extendedGraphemeClusterLiteral: localString) // GOOD
let _ = SQLRequest(stringInterpolation: remoteString) // BAD
let _ = SQLRequest(stringInterpolation: remoteString) // $ Alert
let _ = SQLRequest(stringInterpolation: localString) // GOOD
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: 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: 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/")!)
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
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 _ = 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 sql1 = SQL(stringLiteral: "")
sql1.append(sql: remoteString) // BAD
sql1.append(sql: remoteString) // $ Alert
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/")!)
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
tableDefinition.column(sql: remoteString) // BAD
tableDefinition.column(sql: remoteString) // $ Alert
tableDefinition.column(sql: localString) // GOOD
tableDefinition.check(sql: remoteString) // BAD
tableDefinition.check(sql: remoteString) // $ Alert
tableDefinition.check(sql: localString) // GOOD
tableDefinition.constraint(sql: remoteString) // BAD
tableDefinition.constraint(sql: remoteString) // $ Alert
tableDefinition.constraint(sql: localString) // GOOD
}
func test(tableAlteration: TableAlteration) throws {
let localString = "user"
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
tableAlteration.addColumn(sql: remoteString) // BAD
tableAlteration.addColumn(sql: remoteString) // $ Alert
tableAlteration.addColumn(sql: localString) // GOOD
}
func test(columnDefinition: ColumnDefinition) throws {
let localString = "user"
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
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: 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: 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/")!)
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
let _ = TableRecord.select(sql: remoteString) // BAD
let _ = TableRecord.select(sql: remoteString, arguments: StatementArguments()) // BAD
let _ = TableRecord.select(sql: remoteString) // $ Alert
let _ = TableRecord.select(sql: remoteString, arguments: StatementArguments()) // $ Alert
let _ = TableRecord.select(sql: localString) // GOOD
let _ = TableRecord.select(sql: localString, arguments: StatementArguments()) // GOOD
let _ = TableRecord.filter(sql: remoteString) // BAD
let _ = TableRecord.filter(sql: remoteString, arguments: StatementArguments()) // BAD
let _ = TableRecord.filter(sql: remoteString) // $ Alert
let _ = TableRecord.filter(sql: remoteString, arguments: StatementArguments()) // $ Alert
let _ = TableRecord.filter(sql: localString) // GOOD
let _ = TableRecord.filter(sql: localString, arguments: StatementArguments()) // GOOD
let _ = TableRecord.order(sql: remoteString) // BAD
let _ = TableRecord.order(sql: remoteString, arguments: StatementArguments()) // BAD
let _ = TableRecord.order(sql: remoteString) // $ Alert
let _ = TableRecord.order(sql: remoteString, arguments: StatementArguments()) // $ Alert
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/")!)
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
let _ = statementCache.statement(remoteString) // BAD
let _ = statementCache.statement(remoteString) // $ Alert
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/")!)
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
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: 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: 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) // 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: 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: 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) // 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: 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: 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) // 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: 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: 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/")!)
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
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: 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: 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) // 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: 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: 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) // 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: 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: 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) // 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: 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: 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/")!)
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
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: remoteString, arguments: StatementArguments()) // $ Alert
let _ = SQLStatementCursor(database: database, sql: remoteString, arguments: StatementArguments(), prepFlags: 0) // $ Alert
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/")!)
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
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: 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: localString) // GOOD
let _ = CommonTableExpression(named: "", sql: localString, arguments: StatementArguments()) // GOOD
let _ = CommonTableExpression(named: "", columns: [""], sql: localString) // GOOD

View File

@@ -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/")!)
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
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) // BAD
try db.execute(unsafeQuery2) // BAD
try db.execute(unsafeQuery3) // BAD
try db.execute(unsafeQuery1) // $ Alert
try db.execute(unsafeQuery2) // $ Alert
try db.execute(unsafeQuery3) // $ Alert
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) // BAD
let stmt1 = try db.prepare(unsafeQuery3) // $ Alert
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) // BAD
let stmt5 = try Statement(db, remoteString) // $ Alert
try stmt5.run()
// --- more variants ---
let stmt6 = try db.prepare(unsafeQuery1, "") // BAD
let stmt6 = try db.prepare(unsafeQuery1, "") // $ Alert
try stmt6.run()
let stmt7 = try db.prepare(unsafeQuery1, [""]) // BAD
let stmt7 = try db.prepare(unsafeQuery1, [""]) // $ Alert
try stmt7.run()
let stmt8 = try db.prepare(unsafeQuery1, ["username": ""]) // BAD
let stmt8 = try db.prepare(unsafeQuery1, ["username": ""]) // $ Alert
try stmt8.run()
try db.run(unsafeQuery1, "") // BAD
try db.run(unsafeQuery1, "") // $ Alert
try db.run(unsafeQuery1, [""]) // BAD
try db.run(unsafeQuery1, [""]) // $ Alert
try db.run(unsafeQuery1, ["username": ""]) // BAD
try db.run(unsafeQuery1, ["username": ""]) // $ Alert
try db.scalar(unsafeQuery1, "") // BAD
try db.scalar(unsafeQuery1, "") // $ Alert
try db.scalar(unsafeQuery1, [""]) // BAD
try db.scalar(unsafeQuery1, [""]) // $ Alert
try db.scalar(unsafeQuery1, ["username": ""]) // BAD
try db.scalar(unsafeQuery1, ["username": ""]) // $ Alert
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() // BAD
try Statement(db, remoteString).run() // $ Alert
}

View File

@@ -1 +1,2 @@
queries/Security/CWE-089/SqlInjection.ql
query: queries/Security/CWE-089/SqlInjection.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -43,18 +43,18 @@ class MyDatabase {
// --- tests ---
func test_heuristic(db: MyDatabase) throws {
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
_ = MyDatabase() // GOOD
_ = MyDatabase(sql: "some_fixed_sql") // GOOD
_ = MyDatabase(sql: remoteString) // BAD
_ = MyDatabase(sql: remoteString) // $ Alert
db.execute1(remoteString) // BAD
db.execute2(remoteString) // BAD
db.execute3(NSString(string: remoteString)) // BAD
db.execute4(remoteString as! Sql) // BAD
db.execute1(remoteString) // $ Alert
db.execute2(remoteString) // $ Alert
db.execute3(NSString(string: remoteString)) // $ Alert
db.execute4(remoteString as! Sql) // $ Alert
db.query(sql: remoteString) // BAD
db.query(sql: remoteString) // $ Alert
db.query(sqlLiteral: remoteString) // BAD [NOT DETECTED]
db.query(sqlStatement: remoteString) // BAD [NOT DETECTED]
db.query(sqliteStatement: remoteString) // BAD [NOT DETECTED]

View File

@@ -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/")!)
let remoteString = try! String(contentsOf: URL(string: "http://example.com/")!) // $ Source
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) // BAD
let result2 = sqlite3_exec(db, unsafeQuery2, nil, nil, nil) // BAD
let result3 = sqlite3_exec(db, unsafeQuery3, nil, nil, nil) // BAD
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 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) { // BAD
if (sqlite3_prepare(db, unsafeQuery3, -1, &stmt1, nil) == SQLITE_OK) { // $ Alert
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) { // BAD
if (sqlite3_prepare_v2(db, unsafeQuery3, -1, &stmt4, nil) == SQLITE_OK) { // $ Alert
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) { // BAD
if (sqlite3_prepare_v3(db, unsafeQuery3, -1, 0, &stmt5, nil) == SQLITE_OK) { // $ Alert
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) { // BAD
if (sqlite3_prepare16(db, buffer, Int32(data.count), &stmt6, nil) == SQLITE_OK) { // $ Alert
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) { // BAD
if (sqlite3_prepare16_v2(db, buffer, Int32(data.count), &stmt7, nil) == SQLITE_OK) { // $ Alert
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) { // BAD
if (sqlite3_prepare16_v3(db, buffer, Int32(data.count), 0, &stmt8, nil) == SQLITE_OK) { // $ Alert
let result = sqlite3_step(stmt8)
// ...
}

View File

@@ -1 +1,2 @@
queries/Security/CWE-116/BadTagFilter.ql
query: queries/Security/CWE-116/BadTagFilter.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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)
let re1 = try Regex(#"<script.*?>.*?<\/script>"#).ignoresCase(true) // $ Alert
_ = try re1.firstMatch(in: tainted)
// BAD - doesn't match `</script >`
let re2a = try Regex(#"(?is)<script.*?>.*?<\/script>"#)
let re2a = try Regex(#"(?is)<script.*?>.*?<\/script>"#) // $ Alert
_ = try re2a.firstMatch(in: tainted)
// BAD - doesn't match `</script >`
let re2b = try Regex(#"<script.*?>.*?<\/script>"#).ignoresCase(true).dotMatchesNewlines(true)
let re2b = try Regex(#"<script.*?>.*?<\/script>"#).ignoresCase(true).dotMatchesNewlines(true) // $ Alert
_ = 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)
let ns2c = try NSRegularExpression(pattern: #"<script.*?>.*?<\/script>"#, options: options2c) // $ Alert
_ = 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)
let re6 = try Regex(#"<!--.*--!?>"#).ignoresCase(true) // $ Alert
_ = try re6.firstMatch(in: tainted)
// BAD - doesn't match newlines inside the script tag
let re7 = try Regex(#"<script.*?>(.|\s)*?<\/script[^>]*>"#).ignoresCase(true)
let re7 = try Regex(#"<script.*?>(.|\s)*?<\/script[^>]*>"#).ignoresCase(true) // $ Alert
_ = try re7.firstMatch(in: tainted)
// BAD - doesn't match newlines inside the content
let re8 = try Regex(#"<script[^>]*?>.*?<\/script[^>]*>"#).ignoresCase(true)
let re8 = try Regex(#"<script[^>]*?>.*?<\/script[^>]*>"#).ignoresCase(true) // $ Alert
_ = 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)
let re9 = try Regex(#"<script(\s|\w|=|")*?>.*?<\/script[^>]*>"#).ignoresCase(true).dotMatchesNewlines(true) // $ Alert
_ = try re9.firstMatch(in: tainted)
// BAD - does not match double quotes for attribute values
let re10a = try Regex(#"(?is)<script(\s|\w|=|')*?>.*?<\/script[^>]*>"#)
let re10a = try Regex(#"(?is)<script(\s|\w|=|')*?>.*?<\/script[^>]*>"#) // $ Alert
_ = 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)
let re10b = try Regex(#"<script(\s|\w|=|')*?>.*?<\/script[^>]*>"#).ignoresCase(true).dotMatchesNewlines(true) // $ Alert
_ = 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)
let ns10 = try NSRegularExpression(pattern: #"<script(\s|\w|=|')*?>.*?<\/script[^>]*>"#, options: options10) // $ Alert
_ = 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[^>]*>"#)
let re11a = try Regex(#"(?is)<script( |\n|\w|=|'|")*?>.*?<\/script[^>]*>"#) // $ Alert
_ = try re11a.firstMatch(in: tainted)
// BAD - does not match tabs between attributes
let re11b = try Regex(#"<script( |\n|\w|=|'|")*?>.*?<\/script[^>]*>"#).ignoresCase(true).dotMatchesNewlines(true)
let re11b = try Regex(#"<script( |\n|\w|=|'|")*?>.*?<\/script[^>]*>"#).ignoresCase(true).dotMatchesNewlines(true) // $ Alert
_ = 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)
let ns11 = try NSRegularExpression(pattern: #"<script( |\n|\w|=|'|")*?>.*?<\/script[^>]*>"#, options: options11) // $ Alert
_ = ns11.firstMatch(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
// BAD - does not match uppercase SCRIPT tags
let re12a = try Regex(#"(?s)<script.*?>.*?<\/script[^>]*>"#)
let re12a = try Regex(#"(?s)<script.*?>.*?<\/script[^>]*>"#) // $ Alert
_ = try re12a.firstMatch(in: tainted)
// BAD - does not match uppercase SCRIPT tags
let re12b = try Regex(#"<script.*?>.*?<\/script[^>]*>"#).dotMatchesNewlines(true)
let re12b = try Regex(#"<script.*?>.*?<\/script[^>]*>"#).dotMatchesNewlines(true) // $ Alert
_ = try re12b.firstMatch(in: tainted)
// BAD - does not match uppercase SCRIPT tags
let ns12 = try NSRegularExpression(pattern: #"<script.*?>.*?<\/script[^>]*>"#, options: .dotMatchesLineSeparators)
let ns12 = try NSRegularExpression(pattern: #"<script.*?>.*?<\/script[^>]*>"#, options: .dotMatchesLineSeparators) // $ Alert
_ = 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)[^>]*>"#)
let re13a = try Regex(#"(?s)<(script|SCRIPT).*?>.*?<\/(script|SCRIPT)[^>]*>"#) // $ Alert
_ = try re13a.firstMatch(in: tainted)
// BAD - does not match mixed case script tags
let re13b = try Regex(#"<(script|SCRIPT).*?>.*?<\/(script|SCRIPT)[^>]*>"#).dotMatchesNewlines(true)
let re13b = try Regex(#"<(script|SCRIPT).*?>.*?<\/(script|SCRIPT)[^>]*>"#).dotMatchesNewlines(true) // $ Alert
_ = try re13b.firstMatch(in: tainted)
// BAD - does not match mixed case script tags
let ns13 = try NSRegularExpression(pattern: #"<(script|SCRIPT).*?>.*?<\/(script|SCRIPT)[^>]*>"#, options: .dotMatchesLineSeparators)
let ns13 = try NSRegularExpression(pattern: #"<(script|SCRIPT).*?>.*?<\/(script|SCRIPT)[^>]*>"#, options: .dotMatchesLineSeparators) // $ Alert
_ = 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.*>"#)
let re14a = try Regex(#"(?i)<script[^>]*?>[\s\S]*?<\/script.*>"#) // $ Alert
_ = try re14a.firstMatch(in: tainted)
// BAD - doesn't match newlines in the end tag
let re14b = try Regex(#"<script[^>]*?>[\s\S]*?<\/script.*>"#).ignoresCase(true)
let re14b = try Regex(#"<script[^>]*?>[\s\S]*?<\/script.*>"#).ignoresCase(true) // $ Alert
_ = 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)
let ns14 = try NSRegularExpression(pattern: #"<script[^>]*?>[\s\S]*?<\/script.*>"#, options: .caseInsensitive) // $ Alert
_ = 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]*?>"#)
let re16 = try Regex(#"<(?:!--([\S|\s]*?)-->)|([^\/\s>]+)[\S\s]*?>"#) // $ Alert
_ = 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]*?>"#)
let ns16 = try NSRegularExpression(pattern: #"<(?:!--([\S|\s]*?)-->)|([^\/\s>]+)[\S\s]*?>"#) // $ Alert
_ = 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]*?(\/?)>))"#)
let re17 = try Regex(#"<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\/\s>]+)((?:\s+[\w\-:.]+(?:\s*=\s*?(?:(?:"[^"]*")|(?:'[^']*')|[^\s"'\/>]+))?)*)[\S\s]*?(\/?)>))"#) // $ Alert
_ = 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)
let ns17 = try NSRegularExpression(pattern: #"<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\/\s>]+)((?:\s+[\w\-:.]+(?:\s*=\s*?(?:(?:"[^"]*")|(?:'[^']*')|[^\s"'\/>]+))?)*)[\S\s]*?(\/?)>))"#, options: .caseInsensitive) // $ Alert
_ = 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)
let ns2_1 = try NSRegularExpression(pattern: #"<script\b[^>]*>([\s\S]*?)<\/script>"#, options: .caseInsensitive) // $ Alert
_ = 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)
let ns2_2 = try NSRegularExpression(pattern: #"(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|<!(--.*?--\s*)+>)"#, options: .caseInsensitive) // $ Alert
_ = 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+)>))"#)
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
_ = ns2_3.matches(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
// BAD - capture groups
let ns2_4 = try NSRegularExpression(pattern: #"<!--([\w\W]*?)-->|<([^>]*?)>"#)
let ns2_4 = try NSRegularExpression(pattern: #"<!--([\w\W]*?)-->|<([^>]*?)>"#) // $ Alert
_ = 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: #"-->"#)
let ns2_6 = try NSRegularExpression(pattern: #"-->"#) // $ Alert
_ = ns2_6.matches(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
// GOOD

View File

@@ -1 +1,2 @@
queries/Security/CWE-1204/StaticInitializationVector.ql
query: queries/Security/CWE-1204/StaticInitializationVector.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -57,28 +57,28 @@ func test(myPassword: String) {
let myKeyDerivationSettings = RNCryptorKeyDerivationSettings()
let myHandler = {}
let myRandomIV = Data(getRandomArray())
let myConstIV1 = Data(0)
let myConstIV2 = Data(123)
let myConstIV3 = Data([1,2,3,4,5])
let myConstIV4 = Data("iv")
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 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) // BAD
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, encryptionKey: myKey, hmacKey: myHMACKey, iv: myConstIV1, handler: myHandler) // $ Alert
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) // BAD
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, encryptionKey: myKey, HMACKey: myHMACKey, IV: myConstIV2, handler: myHandler) // $ Alert
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) // BAD
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, iv: myConstIV3, encryptionSalt: mySalt, hmacSalt: mySalt2, handler: myHandler) // $ Alert
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) // BAD
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, IV: myConstIV4, encryptionSalt: mySalt, HMACSalt: mySalt2, handler: myHandler) // $ Alert
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) // BAD
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, encryptionKey: myKey, hmacKey: myHMACKey, iv: myConstIV1) // $ Alert
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) // BAD
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, encryptionKey: myKey, HMACKey: myHMACKey, IV: myConstIV2) // $ Alert
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) // BAD
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myPassword, iv: myConstIV3, encryptionSalt: mySalt, hmacSalt: mySalt2) // $ Alert
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) // BAD
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, password: myPassword, IV: myConstIV4, encryptionSalt: mySalt, HMACSalt: mySalt2) // $ Alert
}

View File

@@ -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)
self.init(iv: iv, additionalAuthenticatedData: additionalAuthenticatedData, tagLength: authenticationTag.count, mode: mode) // $ Alert
}
}
@@ -82,7 +82,7 @@ enum Padding: PaddingProtocol {
// Helper functions
func getConstantString() -> String {
"this string is constant"
"this string is constant" // $ Source
}
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]
let iv: Array<UInt8> = [0x2a, 0x3a, 0x80, 0x05, 0xaf, 0x46, 0x58, 0x2d, 0x66, 0x52, 0x10, 0xae, 0x86, 0xd3, 0x8e, 0x8f] // $ Source
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) // BAD
let ab2 = AES(key: keyString, iv: ivString, padding: padding) // BAD
let ab1 = AES(key: keyString, iv: ivString) // $ Alert
let ab2 = AES(key: keyString, iv: ivString, padding: padding) // $ Alert
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) // BAD
let cb1 = ChaCha20(key: keyString, iv: ivString) // $ Alert
let cg1 = ChaCha20(key: keyString, iv: randomIvString) // GOOD
// Blowfish test cases
let bb1 = Blowfish(key: keyString, iv: ivString) // BAD
let bb2 = Blowfish(key: keyString, iv: ivString, padding: padding) // BAD
let bb1 = Blowfish(key: keyString, iv: ivString) // $ Alert
let bb2 = Blowfish(key: keyString, iv: ivString, padding: padding) // $ Alert
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) // BAD
let rb2 = Rabbit(key: key, iv: iv2) // BAD
let rb3 = Rabbit(key: keyString, iv: ivString) // BAD
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 rg1 = Rabbit(key: key, iv: randomIv) // GOOD
let rg2 = Rabbit(key: keyString, iv: randomIvString) // GOOD
// CBC
let cbcb1 = CBC(iv: iv) // BAD
let cbcb1 = CBC(iv: iv) // $ Alert
let cbcg1 = CBC(iv: randomIv) // GOOD
// CFB
let cfbb1 = CFB(iv: iv) // BAD
let cfbb2 = CFB(iv: iv, segmentSize: CFB.SegmentSize.cfb8) // BAD
let cfbb1 = CFB(iv: iv) // $ Alert
let cfbb2 = CFB(iv: iv, segmentSize: CFB.SegmentSize.cfb8) // $ Alert
let cfbg1 = CFB(iv: randomIv) // GOOD
let cfbg2 = CFB(iv: randomIv, segmentSize: CFB.SegmentSize.cfb8) // GOOD
// GCM
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 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 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) // BAD
let ofbb1 = OFB(iv: iv) // $ Alert
let ofbg1 = OFB(iv: randomIv) // GOOD
// PCBC
let pcbcb1 = PCBC(iv: iv) // BAD
let pcbcb1 = PCBC(iv: iv) // $ Alert
let pcbcg1 = PCBC(iv: randomIv) // GOOD
// CCM
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 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 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) // BAD
let ctrb2 = CTR(iv: iv, counter: 0) // BAD
let ctrb1 = CTR(iv: iv) // $ Alert
let ctrb2 = CTR(iv: iv, counter: 0) // $ Alert
let ctrg1 = CTR(iv: randomIv) // GOOD
let ctrg2 = CTR(iv: randomIv, counter: 0) // GOOD
}

View File

@@ -1 +1,2 @@
queries/Security/CWE-1333/ReDoS.ql
query: queries/Security/CWE-1333/ReDoS.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -61,25 +61,25 @@ func myRegexpTests(myUrl: URL) throws {
// Regex
_ = "((a*)*b)" // GOOD (never used)
_ = 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("((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(".*").firstMatch(in: tainted) // GOOD (safe regex)
let str = "((a*)*b)" // BAD
let str = "((a*)*b)" // $ Alert
let regex = try Regex(str)
_ = try regex.firstMatch(in: tainted)
_ = try Regex(#"(?is)X(?:.|\n)*Y"#) // BAD - suggested attack should begin with 'x' or 'X', *not* 'isx' or 'isX'
_ = try Regex(#"(?is)X(?:.|\n)*Y"#) // $ Alert // BAD - suggested attack should begin with 'x' or 'X', *not* 'isx' or 'isX'
// NSRegularExpression
_ = try? NSRegularExpression(pattern: "((a*)*b)") // DUBIOUS (never used) [FLAGGED]
_ = try? NSRegularExpression(pattern: "((a*)*b)") // $ Alert // DUBIOUS (never used) [FLAGGED]
let nsregex1 = try? NSRegularExpression(pattern: "((a*)*b)") // DUBIOUS (never used on tainted input) [FLAGGED]
let nsregex1 = try? NSRegularExpression(pattern: "((a*)*b)") // $ Alert // 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)") // BAD
let nsregex2 = try? NSRegularExpression(pattern: "((a*)*b)") // $ Alert
_ = nsregex2?.stringByReplacingMatches(in: tainted, range: NSRange(location: 0, length: tainted.utf16.count), withTemplate: "")
let nsregex3 = try? NSRegularExpression(pattern: ".*") // GOOD (safe regex)

View File

@@ -1 +1,2 @@
queries/Security/CWE-134/UncontrolledFormatString.ql
query: queries/Security/CWE-134/UncontrolledFormatString.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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) // BAD
NSLogv(format, arglist) // $ Alert
}
}
@@ -88,34 +88,34 @@ class MyString {
}
func tests() throws {
let tainted = try! String(contentsOf: URL(string: "http://example.com")!)
let tainted = try! String(contentsOf: URL(string: "http://example.com")!) // $ Source
_ = String("abc") // GOOD: not a format string
_ = String(tainted) // GOOD: not a format string
_ = String(format: "abc") // GOOD: not tainted
_ = String(format: tainted) // BAD
_ = String(format: tainted) // $ Alert
_ = String(format: "%s", "abc") // GOOD: not tainted
_ = String(format: "%s", tainted) // GOOD: format string itself is not tainted
_ = String(format: tainted, "abc") // BAD
_ = String(format: tainted, tainted) // BAD
_ = String(format: tainted, "abc") // $ Alert
_ = String(format: tainted, tainted) // $ Alert
_ = String(format: tainted, arguments: []) // BAD
_ = String(format: tainted, locale: nil) // BAD
_ = String(format: tainted, locale: nil, arguments: []) // BAD
_ = String.localizedStringWithFormat(tainted) // BAD
_ = String(format: tainted, arguments: []) // $ Alert
_ = String(format: tainted, locale: nil) // $ Alert
_ = String(format: tainted, locale: nil, arguments: []) // $ Alert
_ = String.localizedStringWithFormat(tainted) // $ Alert
_ = NSString(format: NSString(string: tainted), "abc") // BAD
NSString.localizedStringWithFormat(NSString(string: tainted)) // BAD
_ = NSString(format: NSString(string: tainted), "abc") // $ Alert
NSString.localizedStringWithFormat(NSString(string: tainted)) // $ Alert
_ = NSMutableString(format: NSString(string: tainted), "abc") // BAD
NSMutableString.localizedStringWithFormat(NSString(string: tainted)) // BAD
_ = NSMutableString(format: NSString(string: tainted), "abc") // $ Alert
NSMutableString.localizedStringWithFormat(NSString(string: tainted)) // $ Alert
NSLog("abc") // GOOD: not tainted
NSLog(tainted) // BAD
MyLog(tainted) // BAD
NSLog(tainted) // $ Alert
MyLog(tainted) // $ Alert
NSException.raise(NSExceptionName("exception"), format: tainted, arguments: getVaList([])) // BAD
NSException.raise(NSExceptionName("exception"), format: tainted, arguments: getVaList([])) // $ Alert
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") // BAD
_ = String("abc").appendingFormat(tainted, "abc") // $ Alert
_ = 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") // BAD
s.appendFormat(NSString(string: tainted), "abc") // $ Alert
_ = 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") // BAD
_ = dprintf(0, cstr, "abc") // $ Alert
_ = dprintf(0, "%s", cstr) // GOOD: format not tainted
_ = vprintf(cstr, getVaList(["abc"])) // BAD
_ = vprintf(cstr, getVaList(["abc"])) // $ Alert
_ = vprintf("%s", getVaList([cstr])) // GOOD: format not tainted
_ = vfprintf(nil, cstr, getVaList(["abc"])) // BAD
_ = vfprintf(nil, cstr, getVaList(["abc"])) // $ Alert
_ = vfprintf(nil, "%s", getVaList([cstr])) // GOOD: format not tainted
_ = vasprintf_l(nil, nil, cstr, getVaList(["abc"])) // BAD
_ = vasprintf_l(nil, nil, cstr, getVaList(["abc"])) // $ Alert
_ = 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") // BAD
_ = MyString(format: tainted, "abc") // $ Alert
_ = MyString(format: "%s", tainted) // GOOD: format not tainted
_ = MyString(formatString: tainted, "abc") // BAD
_ = MyString(formatString: tainted, "abc") // $ Alert
_ = MyString(formatString: "%s", tainted) // GOOD: format not tainted
}

View File

@@ -1 +1,2 @@
queries/Security/CWE-259/ConstantPassword.ql
query: queries/Security/CWE-259/ConstantPassword.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -66,7 +66,7 @@ func test(cond: Bool) {
let myData = Data(0)
let myRandomPassword = getARandomPassword()
let myConstPassword = "abc123"
let myConstPassword = "abc123" // $ Source
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) // BAD
let _ = try? myDecryptor.decryptData(b, withPassword: myConstPassword) // BAD
let b = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myConstPassword) // $ Alert
let _ = try? myDecryptor.decryptData(b, withPassword: myConstPassword) // $ Alert
let c = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myMaybePassword) // BAD
let _ = try? myDecryptor.decryptData(c, withPassword: myMaybePassword) // BAD
let c = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myMaybePassword) // $ Alert
let _ = try? myDecryptor.decryptData(c, withPassword: myMaybePassword) // $ Alert
// 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) // 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 _ = 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 _ = 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 _ = 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 _ = 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 _ = 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 _ = RNDecryptor(password: myConstPassword, handler: myHandler) // BAD
let _ = RNDecryptor(password: myConstPassword, handler: myHandler) // $ Alert
let _ = try? myDecryptor.decryptData(myData, withPassword: myConstPassword) // BAD
let _ = try? myDecryptor.decryptData(myData, withSettings: kRNCryptorAES256Settings, password: myConstPassword) // BAD
let _ = try? myDecryptor.decryptData(myData, withPassword: myConstPassword) // $ Alert
let _ = try? myDecryptor.decryptData(myData, withSettings: kRNCryptorAES256Settings, password: myConstPassword) // $ Alert
}

View File

@@ -26,7 +26,7 @@ final class Scrypt {
// Helper functions
func getConstantString() -> String {
"this string is constant"
"this string is constant" // $ Source
}
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]
let constantPassword: Array<UInt8> = [0x2a, 0x3a, 0x80, 0x05, 0xaf, 0x46, 0x58, 0x2d, 0x66, 0x52, 0x10, 0xae, 0x86, 0xd3, 0x8e, 0x8f] // $ Source
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) // BAD
let hkdfb2 = HKDF(password: constantStringPassword, salt: randomArray, info: randomArray, keyLength: 0, variant: variant) // BAD
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 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) // BAD
let pbkdf1b2 = PKCS5.PBKDF1(password: constantStringPassword, salt: randomArray, iterations: iterations, keyLength: 0) // BAD
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 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) // BAD
let pbkdf2b2 = PKCS5.PBKDF2(password: constantStringPassword, salt: randomArray, iterations: iterations, keyLength: 0) // BAD
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 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) // BAD
let scryptb2 = Scrypt(password: constantStringPassword, salt: randomArray, dkLen: 64, N: 16384, r: 8, p: 1) // BAD
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 scryptg1 = Scrypt(password: randomPassword, salt: randomArray, dkLen: 64, N: 16384, r: 8, p: 1) // GOOD
}

View File

@@ -1 +1,2 @@
queries/Security/CWE-311/CleartextStorageDatabase.ql
query: queries/Security/CWE-311/CleartextStorageDatabase.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1,2 @@
queries/Security/CWE-311/CleartextTransmission.ql
query: queries/Security/CWE-311/CleartextTransmission.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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));"
let updateQuery = "UPDATE CONTACTS SET NUMBER=\(mobilePhoneNumber) WHERE ID=\(id);"
let insertQuery = "INSERT INTO CONTACTS(ID, NUMBER) VALUES(\(id), \(mobilePhoneNumber));" // $ Source
let updateQuery = "UPDATE CONTACTS SET NUMBER=\(mobilePhoneNumber) WHERE ID=\(id);" // $ Source
let deleteQuery = "DELETE FROM CONTACTS WHERE ID=\(id);"
try db.execute(insertQuery) // BAD (sensitive data)
try db.execute(updateQuery) // BAD (sensitive data)
try db.execute(insertQuery) // $ Alert // BAD (sensitive data)
try db.execute(updateQuery) // $ Alert // BAD (sensitive data)
try db.execute(deleteQuery) // GOOD
_ = try db.prepare(insertQuery).run() // BAD (sensitive data)
_ = try db.prepare(updateQuery).run() // BAD (sensitive data)
_ = try db.prepare(insertQuery).run() // $ Alert // BAD (sensitive data)
_ = try db.prepare(updateQuery).run() // $ Alert // BAD (sensitive data)
_ = try db.prepare(deleteQuery).run() // GOOD
_ = try db.run(insertQuery) // BAD (sensitive data)
_ = try db.run(updateQuery) // BAD (sensitive data)
_ = try db.run(insertQuery) // $ Alert // BAD (sensitive data)
_ = try db.run(updateQuery) // $ Alert // BAD (sensitive data)
_ = try db.run(deleteQuery) // GOOD
_ = try db.scalar(insertQuery) // BAD (sensitive data)
_ = try db.scalar(updateQuery) // BAD (sensitive data)
_ = try db.scalar(insertQuery) // $ Alert // BAD (sensitive data)
_ = try db.scalar(updateQuery) // $ Alert // BAD (sensitive data)
_ = try db.scalar(deleteQuery) // GOOD
_ = try Statement(db, insertQuery).run() // BAD (sensitive data)
_ = try Statement(db, updateQuery).run() // BAD (sensitive data)
_ = try Statement(db, insertQuery).run() // $ Alert // BAD (sensitive data)
_ = try Statement(db, updateQuery).run() // $ Alert // 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() // BAD (sensitive data)
_ = try db.run(varQuery1, mobilePhoneNumber) // BAD (sensitive data)
_ = try db.scalar(varQuery1, mobilePhoneNumber) // BAD (sensitive data)
_ = 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)
let stmt1 = try db.prepare(varQuery1) // GOOD
_ = try stmt1.bind(mobilePhoneNumber).run() // BAD (sensitive data)
_ = try stmt1.run(mobilePhoneNumber) // BAD (sensitive data)
_ = try stmt1.scalar(mobilePhoneNumber) // BAD (sensitive data)
_ = 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)
let varQuery2 = "UPDATE CONTACTS SET NUMBER=? WHERE ID=?;"
_ = 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)
_ = 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)
let stmt2 = try db.prepare(varQuery2) // GOOD
_ = 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)
_ = 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)
let varQuery3 = "UPDATE CONTACTS SET NUMBER=$number WHERE ID=$id;"
_ = 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)
_ = 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)
let stmt3 = try db.prepare(varQuery3) // GOOD
_ = 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)
_ = 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)
// --- 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)) // BAD (sensitive data)
try db.run(table.insert(idExpr <- id, numberExpr <- mobilePhoneNumber)) // $ Alert // BAD (sensitive data)
try db.run(table.update(numberExpr <- "123")) // GOOD
try db.run(table.update(numberExpr <- mobilePhoneNumber)) // BAD (sensitive data)
try db.run(table.update(numberExpr <- mobilePhoneNumber)) // $ Alert // BAD (sensitive data)
try db.run(filter.update(numberExpr <- "123")) // GOOD
try db.run(filter.update(numberExpr <- mobilePhoneNumber)) // BAD (sensitive data)
try db.run(filter.update(numberExpr <- mobilePhoneNumber)) // $ Alert // 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))) // BAD (sensitive data)
try db.run(table.update(numberExpr <- numberExpr.replace("123", with: mobilePhoneNumber))) // $ Alert // BAD (sensitive data)
// (much more complex query construction is possible in SQLite.swift)
let goodMany = [[numberExpr <- "456"]]
let badMany = [[numberExpr <- mobilePhoneNumber]]
let badMany = [[numberExpr <- mobilePhoneNumber]] // $ Source
try db.run(table.insertMany(goodMany)) // GOOD
try db.run(table.insertMany(badMany)) // BAD (sensitive data)
try db.run(table.insertMany(badMany)) // $ Alert // BAD (sensitive data)
try db.run(table.insertMany(or: OnConflict.replace, goodMany)) // GOOD
try db.run(table.insertMany(or: OnConflict.replace, badMany)) // BAD (sensitive data)
try db.run(table.insertMany(or: OnConflict.replace, badMany)) // $ Alert // BAD (sensitive data)
}

View File

@@ -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));"
let updateQuery = "UPDATE PATIENTS SET NOTES=\(medicalNotes) WHERE ID=\(id);"
let insertQuery = "INSERT INTO PATIENTS(ID, NOTES) VALUES(\(id), \(medicalNotes));" // $ Source
let updateQuery = "UPDATE PATIENTS SET NOTES=\(medicalNotes) WHERE ID=\(id);" // $ Source
let deleteQuery = "DELETE FROM PATIENTS WHERE ID=\(id);"
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, insertQuery, nil, nil, nil) // $ Alert // BAD (sensitive data)
let _ = sqlite3_exec(db, updateQuery, nil, nil, nil) // $ Alert // 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) { // BAD (sensitive data)
if (sqlite3_bind_text(stmt1, 2, medicalNotes, -1, SQLITE_TRANSIENT) == SQLITE_OK) { // $ Alert // BAD (sensitive data)
// ...
}
}

View File

@@ -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) // BAD
AF.request("http://example.com/login?p=" + password) // $ Alert
AF.request("http://example.com/login?h=" + harmless) // GOOD (not sensitive)
AF.streamRequest("http://example.com/login?p=" + password) // BAD
AF.streamRequest("http://example.com/login?p=" + password) // $ Alert
AF.streamRequest("http://example.com/login?h=" + harmless) // GOOD (not sensitive)
AF.download("http://example.com/" + email + ".html") // BAD
AF.download("http://example.com/" + email + ".html") // $ Alert
AF.download("http://example.com/" + harmless + ".html") // GOOD (not sensitive)
// sensitive data in parameters

View File

@@ -16,7 +16,7 @@ class NSManagedObject : NSObject
class MyManagedObject : NSManagedObject
{
func setIndirect(value: String) {
setValue(value, forKey: "myKey")
setValue(value, forKey: "myKey") // $ Alert
}
var myValue: String {
@@ -29,7 +29,7 @@ class MyManagedObject : NSManagedObject
}
}
set {
setValue(newValue, forKey: "myKey") // [additional result reported here]
setValue(newValue, forKey: "myKey") // $ Alert // [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") // BAD
obj.setValue(password, forKey: "myKey") // $ Alert
obj.setValue(password_hash, forKey: "myKey") // GOOD (not sensitive)
obj.setPrimitiveValue(password, forKey: "myKey") // BAD
obj.setPrimitiveValue(password, forKey: "myKey") // $ Alert
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") // BAD
obj.setValue(password, forKey: "myKey") // $ Alert
obj.setValue(password_file, forKey: "myKey") // GOOD (not sensitive)
obj.setIndirect(value: password) // BAD [reported on line 19]
obj.setIndirect(value: password) // $ Source // BAD [reported on line 19]
obj.setIndirect(value: password_file) // GOOD (not sensitive)
obj.myValue = password // BAD [also reported on line 32]
obj.myValue = password // $ Alert Source // 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);
obj.setValue(x, forKey: "myKey") // BAD
doSomething(password: x); // $ Source
obj.setValue(x, forKey: "myKey") // $ Alert
let y = getPassword();
obj.setValue(y, forKey: "myKey") // BAD
let y = getPassword(); // $ Source
obj.setValue(y, forKey: "myKey") // $ Alert
let z = MyClass()
obj.setValue(z.harmless, forKey: "myKey") // GOOD (not sensitive)
obj.setValue(z.password, forKey: "myKey") // BAD
obj.setValue(z.password, forKey: "myKey") // $ Alert
}
func test4(obj : NSManagedObject, passwd : String) {
// sanitizers...
var x = passwd;
var y = passwd;
var z = passwd;
var x = passwd; // $ Source
var y = passwd; // $ Source
var z = passwd; // $ Source
obj.setValue(x, forKey: "myKey") // BAD
obj.setValue(y, forKey: "myKey") // BAD
obj.setValue(z, forKey: "myKey") // BAD
obj.setValue(x, forKey: "myKey") // $ Alert
obj.setValue(y, forKey: "myKey") // $ Alert
obj.setValue(z, forKey: "myKey") // $ Alert
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") // BAD
obj.setValue(getCertificate(), forKey: "myKey") // BAD
obj.setValue(generateSecretKey(), forKey: "myKey") // $ Alert
obj.setValue(getCertificate(), forKey: "myKey") // $ Alert
let gen = KeyGen()
let v = gen.generate()

View File

@@ -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 // BAD
obj.myValue = bankAccountNo // $ Alert
obj.myBankAccountNumber = value // BAD [NOT DETECTED]
obj.myBankAccountNumber = bankAccountNo // BAD
obj.myBankAccountNumber = bankAccountNo // $ Alert
obj.myBankAccountNumber2 = value // BAD [NOT DETECTED]
obj.myBankAccountNumber2 = bankAccountNo // BAD
obj.myBankAccountNumber2 = bankAccountNo // $ Alert
obj.notStoredBankAccountNumber = value // GOOD (not stored in the database)
obj.notStoredBankAccountNumber = bankAccountNo // GOOD (not stored in the datbase) [FALSE POSITIVE]
obj.notStoredBankAccountNumber = bankAccountNo // $ Alert // GOOD (not stored in the datbase) [FALSE POSITIVE]
maybeObj?.myValue = value // GOOD (not sensitive)
maybeObj?.myValue = bankAccountNo // BAD
maybeObj?.myValue = bankAccountNo // $ Alert
maybeObj?.myBankAccountNumber = value // BAD [NOT DETECTED]
maybeObj?.myBankAccountNumber = bankAccountNo // BAD
maybeObj?.myBankAccountNumber = bankAccountNo // $ Alert
maybeObj?.myBankAccountNumber2 = value // BAD [NOT DETECTED]
maybeObj?.myBankAccountNumber2 = bankAccountNo // BAD
maybeObj?.myBankAccountNumber2 = bankAccountNo // $ Alert
maybeObj?.notStoredBankAccountNumber = value // GOOD (not stored in the database)
maybeObj?.notStoredBankAccountNumber = bankAccountNo // GOOD (not stored in the datbase) [FALSE POSITIVE]
maybeObj?.notStoredBankAccountNumber = bankAccountNo // $ Alert // GOOD (not stored in the datbase) [FALSE POSITIVE]
}
class testCoreData2_2 {
func myFunc(obj: MyManagedObject2, bankAccountNo: Int) {
obj.myBankAccountNumber = bankAccountNo // BAD
obj.myBankAccountNumber = bankAccountNo // $ Alert
if #available(iOS 10.0, *) {
obj.myBankAccountNumber = bankAccountNo // BAD
obj.myBankAccountNumber = bankAccountNo // $ Alert
} else {
obj.myBankAccountNumber = bankAccountNo // BAD
obj.myBankAccountNumber = bankAccountNo // $ Alert
}
obj.myBankAccountNumber = bankAccountNo // BAD
obj.myBankAccountNumber = bankAccountNo // $ Alert
}
}
@@ -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 // BAD
dbObj.myValue = container.bankAccountNo2 // BAD
dbObj.myValue = container.bankAccountNo // $ Alert
dbObj.myValue = container.bankAccountNo2 // $ Alert
dbObj.myValue = bankAccountNo.value // BAD
dbObj.myValue = bankAccountNo.value2 // BAD
dbObj.myValue = bankAccountNo2.value // BAD
dbObj.myValue = bankAccountNo2.value2 // BAD
dbObj.myValue = bankAccountNo.value // $ Alert
dbObj.myValue = bankAccountNo.value2 // $ Alert
dbObj.myValue = bankAccountNo2.value // $ Alert
dbObj.myValue = bankAccountNo2.value2 // $ Alert
maybeObj?.myValue = container.bankAccountNo // BAD
maybeObj?.myValue = bankAccountNo.value // BAD
maybeObj?.myValue = bankAccountNo2.value2 // BAD
maybeObj?.myValue = container.bankAccountNo // $ Alert
maybeObj?.myValue = bankAccountNo.value // $ Alert
maybeObj?.myValue = bankAccountNo2.value2 // $ Alert
var a = bankAccountNo // sensitive
var a = bankAccountNo // $ Source // sensitive
var b = a.value
dbObj.myValue = b // BAD
dbObj.myValue = b // $ Alert
let c = bankAccountNo // sensitive
let c = bankAccountNo // $ Source // sensitive
var d: MyContainer = MyContainer()
d.value = c.value
dbObj.myValue = d.value // BAD
dbObj.myValue = d.value // $ Alert
dbObj.myValue = d.value2 // GOOD
let e = bankAccountNo // sensitive
let e = bankAccountNo // $ Source // sensitive
var f: MyContainer?
f?.value = e.value
dbObj.myValue = e.value // BAD
dbObj.myValue = e.value2 // GOOD [FALSE POSITIVE]
dbObj.myValue = e.value // $ Alert
dbObj.myValue = e.value2 // $ Alert // GOOD [FALSE POSITIVE]
}

View File

@@ -70,145 +70,145 @@ class CommonTableExpression {
// --- tests ---
func test(database: Database, password: String, harmless: String) {
let _ = database.allStatements(sql: "", arguments: [password]) // BAD
let _ = database.allStatements(sql: "", arguments: [password]) // $ Alert
let _ = database.allStatements(sql: "", arguments: [harmless]) // GOOD
database.execute(sql: "", arguments: [password]) // BAD
database.execute(sql: "", arguments: [password]) // $ Alert
database.execute(sql: "", arguments: [harmless]) // GOOD
}
func testSqlRequest(password: String, harmless: String) {
let _ = SQLRequest(sql: "", arguments: [password]) // BAD
let _ = SQLRequest(sql: "", arguments: [password]) // $ Alert
let _ = SQLRequest(sql: "", arguments: [harmless]) // GOOD
let _ = SQLRequest(sql: "", arguments: [password], adapter: nil) // BAD
let _ = SQLRequest(sql: "", arguments: [password], adapter: nil) // $ Alert
let _ = SQLRequest(sql: "", arguments: [harmless], adapter: nil) // GOOD
let _ = SQLRequest(sql: "", arguments: [password], cached: false) // BAD
let _ = SQLRequest(sql: "", arguments: [password], cached: false) // $ Alert
let _ = SQLRequest(sql: "", arguments: [harmless], cached: false) // GOOD
let _ = SQLRequest(sql: "", arguments: [password], adapter: nil, cached: false) // BAD
let _ = SQLRequest(sql: "", arguments: [password], adapter: nil, cached: false) // $ Alert
let _ = SQLRequest(sql: "", arguments: [harmless], adapter: nil, cached: false) // GOOD
}
func test(sql: SQL, password: String, harmless: String) {
let _ = SQL(sql: "", arguments: [password]) // BAD
let _ = SQL(sql: "", arguments: [password]) // $ Alert
let _ = SQL(sql: "", arguments: [harmless]) // GOOD
sql.append(sql: "", arguments: [password]) // BAD
sql.append(sql: "", arguments: [password]) // $ Alert
sql.append(sql: "", arguments: [harmless]) // GOOD
}
func testSqlStatementCursor(database: Database, password: String, harmless: String) {
let _ = SQLStatementCursor(database: database, sql: "", arguments: [password]) // BAD
let _ = SQLStatementCursor(database: database, sql: "", arguments: [password], prepFlags: 0) // BAD
let _ = SQLStatementCursor(database: database, sql: "", arguments: [password]) // $ Alert
let _ = SQLStatementCursor(database: database, sql: "", arguments: [password], prepFlags: 0) // $ Alert
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]) // BAD
let _ = TableRecord.select(sql: "", arguments: [password]) // $ Alert
let _ = TableRecord.select(sql: "", arguments: [harmless]) // GOOD
let _ = TableRecord.filter(sql: "", arguments: [password]) // BAD
let _ = TableRecord.filter(sql: "", arguments: [password]) // $ Alert
let _ = TableRecord.filter(sql: "", arguments: [harmless]) // GOOD
let _ = TableRecord.order(sql: "", arguments: [password]) // BAD
let _ = TableRecord.order(sql: "", arguments: [password]) // $ Alert
let _ = TableRecord.order(sql: "", arguments: [harmless]) // GOOD
}
func test(row: Row, stmt: Statement, password: String, harmless: String) {
row.fetchCursor(stmt, sql: "", arguments: [password]) // BAD
row.fetchCursor(stmt, sql: "", arguments: [password]) // $ Alert
row.fetchCursor(stmt, sql: "", arguments: [harmless]) // GOOD
row.fetchCursor(stmt, sql: "", arguments: [password], adapter: nil) // BAD
row.fetchCursor(stmt, sql: "", arguments: [password], adapter: nil) // $ Alert
row.fetchCursor(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
row.fetchAll(stmt, sql: "", arguments: [password]) // BAD
row.fetchAll(stmt, sql: "", arguments: [password]) // $ Alert
row.fetchAll(stmt, sql: "", arguments: [harmless]) // GOOD
row.fetchAll(stmt, sql: "", arguments: [password], adapter: nil) // BAD
row.fetchAll(stmt, sql: "", arguments: [password], adapter: nil) // $ Alert
row.fetchAll(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
row.fetchSet(stmt, sql: "", arguments: [password]) // BAD
row.fetchSet(stmt, sql: "", arguments: [password]) // $ Alert
row.fetchSet(stmt, sql: "", arguments: [harmless]) // GOOD
row.fetchSet(stmt, sql: "", arguments: [password], adapter: nil) // BAD
row.fetchSet(stmt, sql: "", arguments: [password], adapter: nil) // $ Alert
row.fetchSet(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
row.fetchOne(stmt, sql: "", arguments: [password]) // BAD
row.fetchOne(stmt, sql: "", arguments: [password]) // $ Alert
row.fetchOne(stmt, sql: "", arguments: [harmless]) // GOOD
row.fetchOne(stmt, sql: "", arguments: [password], adapter: nil) // BAD
row.fetchOne(stmt, sql: "", arguments: [password], adapter: nil) // $ Alert
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]) // BAD
databaseValueConvertible.fetchCursor(stmt, sql: "", arguments: [password]) // $ Alert
databaseValueConvertible.fetchCursor(stmt, sql: "", arguments: [harmless]) // GOOD
databaseValueConvertible.fetchCursor(stmt, sql: "", arguments: [password], adapter: nil) // BAD
databaseValueConvertible.fetchCursor(stmt, sql: "", arguments: [password], adapter: nil) // $ Alert
databaseValueConvertible.fetchCursor(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
databaseValueConvertible.fetchAll(stmt, sql: "", arguments: [password]) // BAD
databaseValueConvertible.fetchAll(stmt, sql: "", arguments: [password]) // $ Alert
databaseValueConvertible.fetchAll(stmt, sql: "", arguments: [harmless]) // GOOD
databaseValueConvertible.fetchAll(stmt, sql: "", arguments: [password], adapter: nil) // BAD
databaseValueConvertible.fetchAll(stmt, sql: "", arguments: [password], adapter: nil) // $ Alert
databaseValueConvertible.fetchAll(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
databaseValueConvertible.fetchSet(stmt, sql: "", arguments: [password]) // BAD
databaseValueConvertible.fetchSet(stmt, sql: "", arguments: [password]) // $ Alert
databaseValueConvertible.fetchSet(stmt, sql: "", arguments: [harmless]) // GOOD
databaseValueConvertible.fetchSet(stmt, sql: "", arguments: [password], adapter: nil) // BAD
databaseValueConvertible.fetchSet(stmt, sql: "", arguments: [password], adapter: nil) // $ Alert
databaseValueConvertible.fetchSet(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
databaseValueConvertible.fetchOne(stmt, sql: "", arguments: [password]) // BAD
databaseValueConvertible.fetchOne(stmt, sql: "", arguments: [password]) // $ Alert
databaseValueConvertible.fetchOne(stmt, sql: "", arguments: [harmless]) // GOOD
databaseValueConvertible.fetchOne(stmt, sql: "", arguments: [password], adapter: nil) // BAD
databaseValueConvertible.fetchOne(stmt, sql: "", arguments: [password], adapter: nil) // $ Alert
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]) // BAD
fetchableRecord.fetchCursor(stmt, arguments: [password]) // BAD
fetchableRecord.fetchCursor(stmt, sql: "", arguments: [password]) // $ Alert
fetchableRecord.fetchCursor(stmt, arguments: [password]) // $ Alert
fetchableRecord.fetchCursor(stmt, sql: "", arguments: [harmless]) // GOOD
fetchableRecord.fetchCursor(stmt, arguments: [harmless]) // GOOD
fetchableRecord.fetchCursor(stmt, sql: "", arguments: [password], adapter: nil) // BAD
fetchableRecord.fetchCursor(stmt, arguments: [password], adapter: nil) // BAD
fetchableRecord.fetchCursor(stmt, sql: "", arguments: [password], adapter: nil) // $ Alert
fetchableRecord.fetchCursor(stmt, arguments: [password], adapter: nil) // $ Alert
fetchableRecord.fetchCursor(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
fetchableRecord.fetchCursor(stmt, arguments: [harmless], adapter: nil) // GOOD
fetchableRecord.fetchAll(stmt, sql: "", arguments: [password]) // BAD
fetchableRecord.fetchAll(stmt, arguments: [password]) // BAD
fetchableRecord.fetchAll(stmt, sql: "", arguments: [password]) // $ Alert
fetchableRecord.fetchAll(stmt, arguments: [password]) // $ Alert
fetchableRecord.fetchAll(stmt, sql: "", arguments: [harmless]) // GOOD
fetchableRecord.fetchAll(stmt, arguments: [harmless]) // GOOD
fetchableRecord.fetchAll(stmt, sql: "", arguments: [password], adapter: nil) // BAD
fetchableRecord.fetchAll(stmt, arguments: [password], adapter: nil) // BAD
fetchableRecord.fetchAll(stmt, sql: "", arguments: [password], adapter: nil) // $ Alert
fetchableRecord.fetchAll(stmt, arguments: [password], adapter: nil) // $ Alert
fetchableRecord.fetchAll(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
fetchableRecord.fetchAll(stmt, arguments: [harmless], adapter: nil) // GOOD
fetchableRecord.fetchSet(stmt, sql: "", arguments: [password]) // BAD
fetchableRecord.fetchSet(stmt, arguments: [password]) // BAD
fetchableRecord.fetchSet(stmt, sql: "", arguments: [password]) // $ Alert
fetchableRecord.fetchSet(stmt, arguments: [password]) // $ Alert
fetchableRecord.fetchSet(stmt, sql: "", arguments: [harmless]) // GOOD
fetchableRecord.fetchSet(stmt, arguments: [harmless]) // GOOD
fetchableRecord.fetchSet(stmt, sql: "", arguments: [password], adapter: nil) // BAD
fetchableRecord.fetchSet(stmt, arguments: [password], adapter: nil) // BAD
fetchableRecord.fetchSet(stmt, sql: "", arguments: [password], adapter: nil) // $ Alert
fetchableRecord.fetchSet(stmt, arguments: [password], adapter: nil) // $ Alert
fetchableRecord.fetchSet(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
fetchableRecord.fetchSet(stmt, arguments: [harmless], adapter: nil) // GOOD
fetchableRecord.fetchOne(stmt, sql: "", arguments: [password]) // BAD
fetchableRecord.fetchOne(stmt, arguments: [password]) // BAD
fetchableRecord.fetchOne(stmt, sql: "", arguments: [password]) // $ Alert
fetchableRecord.fetchOne(stmt, arguments: [password]) // $ Alert
fetchableRecord.fetchOne(stmt, sql: "", arguments: [harmless]) // GOOD
fetchableRecord.fetchOne(stmt, arguments: [harmless]) // GOOD
fetchableRecord.fetchOne(stmt, sql: "", arguments: [password], adapter: nil) // BAD
fetchableRecord.fetchOne(stmt, arguments: [password], adapter: nil) // BAD
fetchableRecord.fetchOne(stmt, sql: "", arguments: [password], adapter: nil) // $ Alert
fetchableRecord.fetchOne(stmt, arguments: [password], adapter: nil) // $ Alert
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]) // BAD
stmt.execute(arguments: [password]) // $ Alert
stmt.execute(arguments: [harmless]) // GOOD
stmt.setArguments([password]) // BAD
stmt.setArguments([password]) // $ Alert
stmt.setArguments([harmless]) // GOOD
}
func testCommonTableExpression(password: String, harmless: String) {
let _ = CommonTableExpression(named: "", sql: "", arguments: [password]) // BAD
let _ = CommonTableExpression(named: "", sql: "", arguments: [password]) // $ Alert
let _ = CommonTableExpression(named: "", sql: "", arguments: [harmless]) // GOOD
let _ = CommonTableExpression(named: "", columns: nil, sql: "", arguments: [password]) // BAD
let _ = CommonTableExpression(named: "", columns: nil, sql: "", arguments: [password]) // $ Alert
let _ = CommonTableExpression(named: "", columns: nil, sql: "", arguments: [harmless]) // GOOD
let _ = CommonTableExpression(recursive: false, named: "", sql: "", arguments: [password]) // BAD
let _ = CommonTableExpression(recursive: false, named: "", sql: "", arguments: [password]) // $ Alert
let _ = CommonTableExpression(recursive: false, named: "", sql: "", arguments: [harmless]) // GOOD
let _ = CommonTableExpression(recursive: false, named: "", columns: nil, sql: "", arguments: [password]) // BAD
let _ = CommonTableExpression(recursive: false, named: "", columns: nil, sql: "", arguments: [password]) // $ Alert
let _ = CommonTableExpression(recursive: false, named: "", columns: nil, sql: "", arguments: [harmless]) // GOOD
}

View File

@@ -38,7 +38,7 @@ func test1(realm : Realm, myHarmless: String, myPassword : String, myHashedPassw
// add objects (within a transaction) ...
let a = MyRealmSwiftObject()
a.data = myPassword // BAD
a.data = myPassword // $ Alert
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 // BAD
c.data = myPassword // $ Alert
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 // BAD
e!.data = myPassword // $ Alert
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 // BAD
g.data = myPassword // $ Alert
g.data = "" // GOOD (not sensitive)
// MyRealmSwiftObject2...
let h = MyRealmSwiftObject2()
h.harmless = myHarmless // GOOD (not sensitive)
h.password = myPassword // BAD
h.password = myPassword // $ Alert
realm.add(h)
}

View File

@@ -15,23 +15,23 @@ class MyRealmSwiftObject3 : Object {
func test1(o: MyRealmSwiftObject3, myHarmless: String, myPassword: String) {
// ...
o.data = myPassword // BAD
o.data = myPassword // $ Alert
o.data = myHarmless
// ...
}
func test2(o: MyRealmSwiftObject3, ccn: String, socialSecurityNumber: String, ssn: String, ssn_int: Int, userSSN: String, classno: String) {
o.data = socialSecurityNumber // BAD
o.data = ssn // BAD
o.data = String(ssn_int) // BAD
o.data = socialSecurityNumber // $ Alert
o.data = ssn // $ Alert
o.data = String(ssn_int) // $ Alert
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 // BAD
o.data = CCN // BAD
o.data = String(int_ccn) // BAD
o.data = creditCardNumber // $ Alert
o.data = CCN // $ Alert
o.data = String(int_ccn) // $ Alert
o.data = userCcn // BAD [NOT DETECTED]
o.data = succnode // GOOD
}

View File

@@ -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) // BAD
nw.send(content: passwordPlain, completion: .idempotent) // $ Alert
nw.send(content: passwordHash, completion: .idempotent) // GOOD (not sensitive)
let data1 = Data("123456")
let data2 = Data(passwordPlain)
let data2 = Data(passwordPlain) // $ Source
let data3 = Data(passwordHash)
nw.send(content: data1, completion: .idempotent) // GOOD (not sensitive)
nw.send(content: data2, completion: .idempotent) // BAD
nw.send(content: data2, completion: .idempotent) // $ Alert
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
let str2 = password + " "
let str3 = pad(password)
let str1 = password // $ Source
let str2 = password + " " // $ Source
let str3 = pad(password) // $ Source
let str4 = aes_crypt(password)
let str5 = pad(aes_crypt(password))
let str6 = aes_crypt(pad(password))
connection.send(content: str1, completion: .idempotent) // BAD
connection.send(content: str2, completion: .idempotent) // BAD
connection.send(content: str3, completion: .idempotent) // BAD
connection.send(content: str1, completion: .idempotent) // $ Alert
connection.send(content: str2, completion: .idempotent) // $ Alert
connection.send(content: str3, completion: .idempotent) // $ Alert
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) // BAD
connection.send(content: ms.mobileNumber, completion: .idempotent) // BAD
connection.send(content: license_key, completion: .idempotent) // $ Alert
connection.send(content: ms.mobileNumber, completion: .idempotent) // $ Alert
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) // 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
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
}
struct MyOuter {
@@ -91,6 +91,6 @@ struct MyOuter {
}
func test3(mo : MyOuter, connection : NWConnection) {
connection.send(content: mo.password.value, completion: .idempotent) // BAD
connection.send(content: mo.password.value, completion: .idempotent) // $ Alert
connection.send(content: mo.harmless.value, completion: .idempotent) // GOOD
}

View File

@@ -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); // BAD
_ = URL(string: "http://example.com/login?p=" + passwd); // $ Alert
_ = URL(string: "http://example.com/login?p=" + encrypted_passwd); // GOOD (not sensitive)
_ = URL(string: "http://example.com/login?ac=" + account_no); // BAD
_ = URL(string: "http://example.com/login?cc=" + credit_card_no); // BAD
_ = URL(string: "http://example.com/login?ac=" + account_no); // $ Alert
_ = URL(string: "http://example.com/login?cc=" + credit_card_no); // $ Alert
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); // BAD
let f = URL(string: passwd, relativeTo: base); // $ Alert
_ = URL(string: "abc", relativeTo: f); // BAD (reported on line above)
let e_mail = myString
_ = URL(string: "http://example.com/login?em=" + e_mail); // BAD
_ = URL(string: "http://example.com/login?em=" + e_mail); // $ Alert
let a_homeaddr_z = getMyString()
_ = URL(string: "http://example.com/login?home=" + a_homeaddr_z); // BAD
_ = URL(string: "http://example.com/login?home=" + a_homeaddr_z); // $ Alert
let resident_ID = getMyString()
_ = URL(string: "http://example.com/login?id=" + resident_ID); // BAD
_ = URL(string: "http://example.com/login?id=" + resident_ID); // $ Alert
}
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()); // BAD
_ = URL(string: "http://example.com/login?key=" + get_secret_key()); // $ Alert
_ = URL(string: "http://example.com/login?key=" + get_key_press()); // GOOD (not sensitive)
_ = URL(string: "http://example.com/login?cert=" + get_cert_string()); // BAD
_ = URL(string: "http://example.com/login?cert=" + get_cert_string()); // $ Alert
_ = 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)"); // BAD
_ = URL(string: "http://example.com/login?cert=\(certificate)"); // $ Alert
_ = 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 {
if let data = SecKeyCopyExternalRepresentation(key, nil) as? Data { // $ Source
if let string = String(data: data, encoding: .utf8) {
_ = URL(string: "http://example.com/login?tok=\(string)"); // BAD
_ = URL(string: "http://example.com/login?tok=\(string)"); // $ Alert
}
}
}
@@ -113,14 +113,14 @@ func test5() {
let email = get_string()
let secret_key = get_string()
_ = URL(string: "http://example.com/login?email=\(email)"); // BAD
_ = URL(string: "http://example.com/login?email=\(email)"); // $ Alert
_ = 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)"); // BAD
_ = URL(string: "http://example.com/profile?tel=\(phone_number)"); // $ Alert
_ = 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") // BAD
_ = URL(string: "ftp://example.com/\(account_no).csv") // $ Alert
}

View File

@@ -1 +1,2 @@
queries/Security/CWE-312/CleartextStoragePreferences.ql
query: queries/Security/CWE-312/CleartextStoragePreferences.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -25,7 +25,7 @@ func doSomething(password: String) { }
func test1(password: String, passwordHash : String) {
let store = NSUbiquitousKeyValueStore.default
store.set(password, forKey: "myKey") // BAD
store.set(password, forKey: "myKey") // $ Alert
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);
NSUbiquitousKeyValueStore.default.set(x, forKey: "myKey") // BAD
doSomething(password: x); // $ Source
NSUbiquitousKeyValueStore.default.set(x, forKey: "myKey") // $ Alert
let y = getPassword();
NSUbiquitousKeyValueStore.default.set(y, forKey: "myKey") // BAD
let y = getPassword(); // $ Source
NSUbiquitousKeyValueStore.default.set(y, forKey: "myKey") // $ Alert
let z = MyClass()
NSUbiquitousKeyValueStore.default.set(z.harmless, forKey: "myKey") // GOOD (not sensitive)
NSUbiquitousKeyValueStore.default.set(z.password, forKey: "myKey") // BAD
NSUbiquitousKeyValueStore.default.set(z.password, forKey: "myKey") // $ Alert
}
func test4(passwd: String) {
// sanitizers...
var x = passwd;
var y = passwd;
var z = passwd;
var x = passwd; // $ Source
var y = passwd; // $ Source
var z = passwd; // $ Source
NSUbiquitousKeyValueStore.default.set(x, forKey: "myKey") // BAD
NSUbiquitousKeyValueStore.default.set(y, forKey: "myKey") // BAD
NSUbiquitousKeyValueStore.default.set(z, forKey: "myKey") // BAD
NSUbiquitousKeyValueStore.default.set(x, forKey: "myKey") // $ Alert
NSUbiquitousKeyValueStore.default.set(y, forKey: "myKey") // $ Alert
NSUbiquitousKeyValueStore.default.set(z, forKey: "myKey") // $ Alert
x = encrypt(x);
hash(data: &y);

View File

@@ -25,7 +25,7 @@ func doSomething(password: String) { }
func test1(password: String, passwordHash : String) {
let defaults = UserDefaults.standard
defaults.set(password, forKey: "myKey") // BAD
defaults.set(password, forKey: "myKey") // $ Alert
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);
UserDefaults.standard.set(x, forKey: "myKey") // BAD
doSomething(password: x); // $ Source
UserDefaults.standard.set(x, forKey: "myKey") // $ Alert
let y = getPassword();
UserDefaults.standard.set(y, forKey: "myKey") // BAD
let y = getPassword(); // $ Source
UserDefaults.standard.set(y, forKey: "myKey") // $ Alert
let z = MyClass()
UserDefaults.standard.set(z.harmless, forKey: "myKey") // GOOD (not sensitive)
UserDefaults.standard.set(z.password, forKey: "myKey") // BAD
UserDefaults.standard.set(z.password, forKey: "myKey") // $ Alert
}
func test4(passwd: String) {
// sanitizers...
var x = passwd;
var y = passwd;
var z = passwd;
var x = passwd; // $ Source
var y = passwd; // $ Source
var z = passwd; // $ Source
UserDefaults.standard.set(x, forKey: "myKey") // BAD
UserDefaults.standard.set(y, forKey: "myKey") // BAD
UserDefaults.standard.set(z, forKey: "myKey") // BAD
UserDefaults.standard.set(x, forKey: "myKey") // $ Alert
UserDefaults.standard.set(y, forKey: "myKey") // $ Alert
UserDefaults.standard.set(z, forKey: "myKey") // $ Alert
x = encrypt(x);
hash(data: &y);
@@ -79,6 +79,6 @@ struct MyOuter {
}
func test5(mo : MyOuter) {
UserDefaults.standard.set(mo.password.value, forKey: "myKey") // BAD
UserDefaults.standard.set(mo.password.value, forKey: "myKey") // $ Alert
UserDefaults.standard.set(mo.harmless.value, forKey: "myKey") // GOOD
}

View File

@@ -1 +1,2 @@
queries/Security/CWE-327/ECBEncryption.ql
query: queries/Security/CWE-327/ECBEncryption.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -36,7 +36,7 @@ func getRandomArray() -> Array<UInt8> {
}
func getECBBlockMode() -> BlockMode {
return ECB()
return ECB() // $ Source
}
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()
let ecb = ECB() // $ Source
let iv = getRandomArray()
let cbc = CBC(iv: iv)
let padding = Padding.noPadding
// AES test cases
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 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 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) // BAD
let bb2 = Blowfish(key: key, blockMode: ECB(), padding: padding) // BAD
let bb3 = Blowfish(key: key, blockMode: getECBBlockMode(), padding: padding) // BAD
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 bg1 = Blowfish(key: key, blockMode: cbc, padding: padding) // GOOD
let bg2 = Blowfish(key: key, blockMode: CBC(iv: iv), padding: padding) // GOOD

View File

@@ -1 +1,2 @@
queries/Security/CWE-328/WeakPasswordHashing.ql
query: queries/Security/CWE-328/WeakPasswordHashing.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1,2 @@
queries/Security/CWE-328/WeakSensitiveDataHashing.ql
query: queries/Security/CWE-328/WeakSensitiveDataHashing.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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) // BAD
hash = Crypto.Insecure.MD5.hash(bufferPointer: passwd) // BAD
hash = Crypto.Insecure.MD5.hash(data: cert) // BAD
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
hash = Crypto.Insecure.MD5.hash(data: encrypted_passwd) // GOOD (not sensitive)
hash = Crypto.Insecure.MD5.hash(data: account_no) // BAD
hash = Crypto.Insecure.MD5.hash(data: credit_card_no) // BAD
hash = Crypto.Insecure.MD5.hash(data: account_no) // $ Alert
hash = Crypto.Insecure.MD5.hash(data: credit_card_no) // $ 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: passwd) // $ Alert
hash = Insecure.MD5.hash(bufferPointer: passwd) // $ Alert
hash = Insecure.MD5.hash(data: cert) // $ Alert
hash = Insecure.MD5.hash(data: encrypted_passwd) // GOOD (not sensitive)
hash = Insecure.MD5.hash(data: account_no) // BAD
hash = Insecure.MD5.hash(data: credit_card_no) // BAD
hash = Insecure.MD5.hash(data: account_no) // $ Alert
hash = Insecure.MD5.hash(data: credit_card_no) // $ 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: passwd) // $ Alert
hash = Crypto.Insecure.SHA1.hash(bufferPointer: passwd) // $ Alert
hash = Crypto.Insecure.SHA1.hash(data: cert) // $ Alert
hash = Crypto.Insecure.SHA1.hash(data: encrypted_passwd) // GOOD (not sensitive)
hash = Crypto.Insecure.SHA1.hash(data: account_no) // BAD
hash = Crypto.Insecure.SHA1.hash(data: credit_card_no) // BAD
hash = Crypto.Insecure.SHA1.hash(data: account_no) // $ Alert
hash = Crypto.Insecure.SHA1.hash(data: credit_card_no) // $ Alert
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: 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: 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) // BAD, not a computationally expensive hash
hash = Crypto.SHA384.hash(bufferPointer: passwd) // BAD, not a computationally expensive hash
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: 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) // BAD, not a computationally expensive hash
hash = Crypto.SHA512.hash(bufferPointer: passwd) // BAD, not a computationally expensive hash
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: 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) // BAD
hash.update(data: cert) // BAD
hash.update(data: passwd) // $ Alert
hash.update(data: cert) // $ Alert
hash.update(data: encrypted_passwd) // GOOD (not sensitive)
hash.update(data: account_no) // BAD
hash.update(data: credit_card_no) // BAD
hash.update(data: account_no) // $ Alert
hash.update(data: credit_card_no) // $ Alert
}
func testSHA1UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) {
var hash = Crypto.Insecure.SHA1()
hash.update(data: passwd) // BAD
hash.update(data: cert) // BAD
hash.update(data: passwd) // $ Alert
hash.update(data: cert) // $ Alert
hash.update(data: encrypted_passwd) // GOOD (not sensitive)
hash.update(data: account_no) // BAD
hash.update(data: credit_card_no) // BAD
hash.update(data: account_no) // $ Alert
hash.update(data: credit_card_no) // $ Alert
}
func testSHA256UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) {
var hash = Crypto.SHA256()
hash.update(data: passwd) // BAD, not a computationally expensive hash
hash.update(data: passwd) // $ Alert // 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) // BAD, not a computationally expensive hash
hash.update(data: passwd) // $ Alert // 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) // BAD, not a computationally expensive hash
hash.update(data: passwd) // $ Alert // 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) // BAD
hash.update(bufferPointer: cert) // BAD
hash.update(bufferPointer: passwd) // $ Alert
hash.update(bufferPointer: cert) // $ Alert
hash.update(bufferPointer: encrypted_passwd) // GOOD (not sensitive)
hash.update(bufferPointer: account_no) // BAD
hash.update(bufferPointer: credit_card_no) // BAD
hash.update(bufferPointer: account_no) // $ Alert
hash.update(bufferPointer: credit_card_no) // $ Alert
}
func testSHA1UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer, cert: UnsafeRawBufferPointer, encrypted_passwd : UnsafeRawBufferPointer, account_no : UnsafeRawBufferPointer, credit_card_no : UnsafeRawBufferPointer) {
var hash = Crypto.Insecure.SHA1()
hash.update(bufferPointer: passwd) // BAD
hash.update(bufferPointer: cert) // BAD
hash.update(bufferPointer: passwd) // $ Alert
hash.update(bufferPointer: cert) // $ Alert
hash.update(bufferPointer: encrypted_passwd) // GOOD (not sensitive)
hash.update(bufferPointer: account_no) // BAD
hash.update(bufferPointer: credit_card_no) // BAD
hash.update(bufferPointer: account_no) // $ Alert
hash.update(bufferPointer: credit_card_no) // $ Alert
}
func testSHA256UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer, cert: UnsafeRawBufferPointer, encrypted_passwd : UnsafeRawBufferPointer, account_no : UnsafeRawBufferPointer, credit_card_no : UnsafeRawBufferPointer) {
var hash = Crypto.SHA256()
hash.update(bufferPointer: passwd) // BAD, not a computationally expensive hash
hash.update(bufferPointer: passwd) // $ Alert // 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) // BAD, not a computationally expensive hash
hash.update(bufferPointer: passwd) // $ Alert // 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) // BAD, not a computationally expensive hash
hash.update(bufferPointer: passwd) // $ Alert // 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) // BAD, not a computationally expensive hash
let passwordHash = Crypto.SHA512.hash(data: passwordData) // $ Alert // BAD, not a computationally expensive hash
// ...
if Crypto.SHA512.hash(data: Data(passwordString.utf8)) == passwordHash { // BAD, not a computationally expensive hash
if Crypto.SHA512.hash(data: Data(passwordString.utf8)) == passwordHash { // $ Alert // BAD, not a computationally expensive hash
// ...
}
}
func testWithFlowAndMetatypes(cardNumber: String) {
let value1 = Data(cardNumber.utf8);
let _digest1 = Insecure.MD5.hash(data: value1); // BAD
let value1 = Data(cardNumber.utf8); // $ Source
let _digest1 = Insecure.MD5.hash(data: value1); // $ Alert
let value2 = Data(cardNumber.utf8);
let value2 = Data(cardNumber.utf8); // $ Source
let hasher2 = Insecure.MD5.self; // metatype
let _digest2 = hasher2.hash(data: value2); // BAD
let _digest2 = hasher2.hash(data: value2); // $ Alert
let value3 = Data(cardNumber.utf8);
let _digest3 = (Insecure.MD5.self).hash(data: value3); // BAD
let value3 = Data(cardNumber.utf8); // $ Source
let _digest3 = (Insecure.MD5.self).hash(data: value3); // $ Alert
let value4 = Data(cardNumber.utf8);
let value4 = Data(cardNumber.utf8); // $ Source
testReceiver1(value: value4);
let value5 = Data(cardNumber.utf8);
let value5 = Data(cardNumber.utf8); // $ Source
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); // BAD
let _digest = Insecure.MD5.hash(data: value); // $ Alert
}
func testReceiver2(hasher: Insecure.MD5.Type, value: Data) {
let _digest = hasher.hash(data: value); // BAD
let _digest = hasher.hash(data: value); // $ Alert
}
func testReceiver3<H: HashFunction>(hasher: H.Type, value: Data) {

View File

@@ -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) // BAD
_ = MD5().calculate(for: passwdArray) // BAD
_ = MD5().calculate(for: phoneNumberArray) // $ Alert
_ = MD5().calculate(for: passwdArray) // $ Alert
_ = SHA1().calculate(for: harmlessArray) // GOOD (not sensitive)
_ = SHA1().calculate(for: phoneNumberArray) // BAD
_ = SHA1().calculate(for: passwdArray) // BAD
_ = SHA1().calculate(for: phoneNumberArray) // $ Alert
_ = SHA1().calculate(for: passwdArray) // $ Alert
_ = SHA2(variant: .sha512).calculate(for: harmlessArray) // GOOD
_ = SHA2(variant: .sha512).calculate(for: phoneNumberArray) // GOOD
_ = SHA2(variant: .sha512).calculate(for: passwdArray) // BAD
_ = SHA2(variant: .sha512).calculate(for: passwdArray) // $ Alert
_ = SHA3(variant: .sha512).calculate(for: harmlessArray) // GOOD
_ = SHA3(variant: .sha512).calculate(for: phoneNumberArray) // GOOD
_ = SHA3(variant: .sha512).calculate(for: passwdArray) // BAD
_ = SHA3(variant: .sha512).calculate(for: passwdArray) // $ Alert
_ = Digest.md5(harmlessArray) // GOOD (not sensitive)
_ = Digest.md5(phoneNumberArray) // BAD
_ = Digest.md5(passwdArray) // BAD
_ = Digest.md5(phoneNumberArray) // $ Alert
_ = Digest.md5(passwdArray) // $ Alert
_ = Digest.sha1(harmlessArray) // GOOD (not sensitive)
_ = Digest.sha1(phoneNumberArray) // BAD
_ = Digest.sha1(passwdArray) // BAD
_ = Digest.sha1(phoneNumberArray) // $ Alert
_ = Digest.sha1(passwdArray) // $ Alert
_ = Digest.sha512(harmlessArray) // GOOD (not sensitive)
_ = Digest.sha512(phoneNumberArray) // GOOD
_ = Digest.sha512(passwdArray) // BAD
_ = Digest.sha512(passwdArray) // $ Alert
_ = Digest.sha2(harmlessArray, variant: .sha512) // GOOD (not sensitive)
_ = Digest.sha2(phoneNumberArray, variant: .sha512) // GOOD
_ = Digest.sha2(passwdArray, variant: .sha512) // BAD
_ = Digest.sha2(passwdArray, variant: .sha512) // $ Alert
_ = Digest.sha3(harmlessArray, variant: .sha512) // GOOD (not sensitive)
_ = Digest.sha3(phoneNumberArray, variant: .sha512) // GOOD
_ = Digest.sha3(passwdArray, variant: .sha512) // BAD
_ = Digest.sha3(passwdArray, variant: .sha512) // $ Alert
_ = harmlessArray.md5() // GOOD (not sensitive)
_ = phoneNumberArray.md5() // BAD
_ = passwdArray.md5() // BAD
_ = phoneNumberArray.md5() // $ Alert
_ = passwdArray.md5() // $ Alert
_ = harmlessArray.sha1() // GOOD (not sensitive)
_ = phoneNumberArray.sha1() // BAD
_ = passwdArray.sha1() // BAD
_ = phoneNumberArray.sha1() // $ Alert
_ = passwdArray.sha1() // $ Alert
_ = harmlessArray.sha512() // GOOD
_ = phoneNumberArray.sha512() // GOOD
_ = passwdArray.sha512() // BAD
_ = passwdArray.sha512() // $ Alert
_ = harmlessArray.sha2(.sha512) // GOOD
_ = phoneNumberArray.sha2(.sha512) // GOOD
_ = passwdArray.sha2(.sha512) // BAD
_ = passwdArray.sha2(.sha512) // $ Alert
_ = harmlessArray.sha3(.sha512) // GOOD
_ = phoneNumberArray.sha3(.sha512) // GOOD
_ = passwdArray.sha3(.sha512) // BAD
_ = passwdArray.sha3(.sha512) // $ Alert
}
func testData(harmlessData: Data, medicalData: Data, passwdData: Data) {
_ = harmlessData.md5() // GOOD (not sensitive)
_ = medicalData.md5() // BAD
_ = passwdData.md5() // BAD
_ = medicalData.md5() // $ Alert
_ = passwdData.md5() // $ Alert
_ = harmlessData.sha1() // GOOD (not sensitive)
_ = medicalData.sha1() // BAD
_ = passwdData.sha1() // BAD
_ = medicalData.sha1() // $ Alert
_ = passwdData.sha1() // $ Alert
_ = harmlessData.sha512() // GOOD
_ = medicalData.sha512() // GOOD
_ = passwdData.sha512() // BAD
_ = passwdData.sha512() // $ Alert
_ = harmlessData.sha2(.sha512) // GOOD
_ = medicalData.sha2(.sha512) // GOOD
_ = passwdData.sha2(.sha512) // BAD
_ = passwdData.sha2(.sha512) // $ Alert
_ = harmlessData.sha3(.sha512) // GOOD
_ = medicalData.sha3(.sha512) // GOOD
_ = passwdData.sha3(.sha512) // BAD
_ = passwdData.sha3(.sha512) // $ Alert
}
func testStrings(creditCardNumber: String, passwd: String) {
_ = "harmless".md5() // GOOD (not sensitive)
_ = creditCardNumber.md5() // BAD
_ = passwd.md5() // BAD
_ = creditCardNumber.md5() // $ Alert
_ = passwd.md5() // $ Alert
_ = "harmless".sha1() // GOOD (not sensitive)
_ = creditCardNumber.sha1() // BAD
_ = passwd.sha1() // BAD
_ = creditCardNumber.sha1() // $ Alert
_ = passwd.sha1() // $ Alert
_ = "harmless".sha512() // GOOD
_ = creditCardNumber.sha512() // GOOD
_ = passwd.sha512() // BAD
_ = passwd.sha512() // $ Alert
_ = "harmless".sha2(.sha512) // GOOD
_ = creditCardNumber.sha2(.sha512) // GOOD
_ = passwd.sha2(.sha512) // BAD
_ = passwd.sha2(.sha512) // $ Alert
_ = "harmless".sha3(.sha512) // GOOD
_ = creditCardNumber.sha3(.sha512) // GOOD
_ = passwd.sha3(.sha512) // BAD
_ = passwd.sha3(.sha512) // $ Alert
}

View File

@@ -1 +1,2 @@
queries/Security/CWE-730/RegexInjection.ql
query: queries/Security/CWE-730/RegexInjection.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -92,59 +92,59 @@ extension String {
func regexInjectionTests(cond: Bool, varString: String, myUrl: URL) throws {
let constString = ".*"
let taintedString = String(contentsOf: myUrl) // tainted
let taintedString = String(contentsOf: myUrl) // $ Source // tainted
// --- Regex ---
_ = try Regex(constString).firstMatch(in: varString)
_ = try Regex(varString).firstMatch(in: varString)
_ = try Regex(taintedString).firstMatch(in: varString) // BAD
_ = try Regex(taintedString).firstMatch(in: varString) // $ Alert
_ = try Regex("(a|" + constString + ")").firstMatch(in: varString)
_ = try Regex("(a|" + taintedString + ")").firstMatch(in: varString) // BAD
_ = try Regex("(a|" + taintedString + ")").firstMatch(in: varString) // $ Alert
_ = try Regex("(a|\(constString))").firstMatch(in: varString)
_ = try Regex("(a|\(taintedString))").firstMatch(in: varString) // BAD
_ = try Regex("(a|\(taintedString))").firstMatch(in: varString) // $ Alert
_ = try Regex(cond ? constString : constString).firstMatch(in: varString)
_ = try Regex(cond ? taintedString : constString).firstMatch(in: varString) // BAD
_ = try Regex(cond ? constString : taintedString).firstMatch(in: varString) // BAD
_ = try Regex(cond ? taintedString : constString).firstMatch(in: varString) // $ Alert
_ = try Regex(cond ? constString : taintedString).firstMatch(in: varString) // $ Alert
_ = try (cond ? Regex(constString) : Regex(constString)).firstMatch(in: varString)
_ = try (cond ? Regex(taintedString) : Regex(constString)).firstMatch(in: varString) // BAD
_ = try (cond ? Regex(constString) : Regex(taintedString)).firstMatch(in: varString) // BAD
_ = try (cond ? Regex(taintedString) : Regex(constString)).firstMatch(in: varString) // $ Alert
_ = try (cond ? Regex(constString) : Regex(taintedString)).firstMatch(in: varString) // $ Alert
// --- RangeReplaceableCollection ---
var inputVar = varString
inputVar.replace(constString, with: "")
inputVar.replace(taintedString, with: "") // BAD
inputVar.replace(taintedString, with: "") // $ Alert
inputVar.replace(constString, with: taintedString)
// --- StringProtocol ---
_ = inputVar.replacingOccurrences(of: constString, with: "", options: .regularExpression)
_ = inputVar.replacingOccurrences(of: taintedString, with: "", options: .regularExpression) // BAD
_ = inputVar.replacingOccurrences(of: taintedString, with: "", options: .regularExpression) // $ Alert
// --- 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)) // BAD
_ = try NSRegularExpression(pattern: taintedString).firstMatch(in: varString, range: NSMakeRange(0, varString.utf16.count)) // $ Alert
// --- 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)) // BAD
_ = nsString.replacingOccurrences(of: taintedString, with: "", options: .regularExpression, range: NSMakeRange(0, nsString.length)) // $ Alert
// --- from the qhelp ---
let remoteInput = taintedString
let myRegex = ".*"
_ = try Regex(remoteInput) // BAD
_ = try Regex(remoteInput) // $ Alert
let regexStr = "abc|\(remoteInput)"
_ = try NSRegularExpression(pattern: regexStr) // BAD
_ = try NSRegularExpression(pattern: regexStr) // $ Alert
_ = 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) // GOOD (effectively sanitized by the check) [FALSE POSITIVE]
_ = try Regex(taintedString).firstMatch(in: varString) // $ Alert // GOOD (effectively sanitized by the check) [FALSE POSITIVE]
} else {
_ = try Regex(taintedString).firstMatch(in: varString) // BAD
_ = try Regex(taintedString).firstMatch(in: varString) // $ Alert
}
if (taintedString != okInput) {
_ = try Regex(taintedString).firstMatch(in: varString) // BAD
_ = try Regex(taintedString).firstMatch(in: varString) // $ Alert
}
if (varString == okInput) {
_ = try Regex(taintedString).firstMatch(in: varString) // BAD
_ = try Regex(taintedString).firstMatch(in: varString) // $ Alert
}
if (okInputs.contains(taintedString)) {
_ = try Regex(taintedString).firstMatch(in: varString) // GOOD (effectively sanitized by the check) [FALSE POSITIVE]
_ = try Regex(taintedString).firstMatch(in: varString) // $ Alert // GOOD (effectively sanitized by the check) [FALSE POSITIVE]
}
if (okInputs.firstIndex(of: taintedString) != nil) {
_ = try Regex(taintedString).firstMatch(in: varString) // GOOD (effectively sanitized by the check) [FALSE POSITIVE]
_ = try Regex(taintedString).firstMatch(in: varString) // $ Alert // GOOD (effectively sanitized by the check) [FALSE POSITIVE]
}
if let index = okInputs.firstIndex(of: taintedString) {
_ = try Regex(taintedString).firstMatch(in: varString) // GOOD (effectively sanitized by the check) [FALSE POSITIVE]
_ = try Regex(taintedString).firstMatch(in: varString) // $ Alert // GOOD (effectively sanitized by the check) [FALSE POSITIVE]
}
if let index = okInputs.index(of: taintedString) {
_ = try Regex(taintedString).firstMatch(in: varString) // GOOD (effectively sanitized by the check) [FALSE POSITIVE]
_ = try Regex(taintedString).firstMatch(in: varString) // $ Alert // GOOD (effectively sanitized by the check) [FALSE POSITIVE]
}
if (okSet.contains(taintedString)) {
_ = try Regex(taintedString).firstMatch(in: varString) // GOOD (effectively sanitized by the check) [FALSE POSITIVE]
_ = try Regex(taintedString).firstMatch(in: varString) // $ Alert // GOOD (effectively sanitized by the check) [FALSE POSITIVE]
}
// --- multiple evaluations ---
let re = try Regex(taintedString) // BAD
let re = try Regex(taintedString) // $ Alert
_ = try re.firstMatch(in: varString) // (we only want to flag one location total)
_ = try re.firstMatch(in: varString)
}

View File

@@ -1 +1,2 @@
queries/Security/CWE-760/ConstantSalt.ql
query: queries/Security/CWE-760/ConstantSalt.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -56,27 +56,27 @@ func test(myPassword: String) {
let myIV = Data(0)
let myRandomSalt1 = Data(getARandomString())
let myRandomSalt2 = Data(getARandomString())
let myConstantSalt1 = Data("abcdef123456")
let myConstantSalt2 = Data(0)
let myConstantSalt1 = Data("abcdef123456") // $ Source
let myConstantSalt2 = Data(0) // $ Source
let _ = myEncryptor.key(forPassword: myPassword, salt: myRandomSalt1, settings: myKeyDerivationSettings) // GOOD
let _ = myEncryptor.key(forPassword: myPassword, salt: myConstantSalt1, settings: myKeyDerivationSettings) // BAD
let _ = myEncryptor.key(forPassword: myPassword, salt: myConstantSalt1, settings: myKeyDerivationSettings) // $ Alert
let _ = myEncryptor.keyForPassword(myPassword, salt: myRandomSalt2, settings: myKeyDerivationSettings) // GOOD
let _ = myEncryptor.keyForPassword(myPassword, salt: myConstantSalt2, settings: myKeyDerivationSettings) // BAD
let _ = myEncryptor.keyForPassword(myPassword, salt: myConstantSalt2, settings: myKeyDerivationSettings) // $ Alert
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) // 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: 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: myRandomSalt1, HMACSalt: myRandomSalt2, handler: myHandler) // GOOD
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: myConstantSalt1, HMACSalt: myRandomSalt2, handler: myHandler) // $ Alert
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, IV: myIV, encryptionSalt: myRandomSalt1, HMACSalt: myConstantSalt2, handler: myHandler) // $ Alert
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) // BAD
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myPassword, iv: myIV, encryptionSalt: myRandomSalt1, hmacSalt: myConstantSalt2) // BAD
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, 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) // BAD
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, password: myPassword, IV: myIV, encryptionSalt: myRandomSalt1, HMACSalt: myConstantSalt2) // BAD
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
// appending constants
let _ = myEncryptor.key(forPassword: myPassword, salt: Data(getARandomString() + getARandomString()), settings: myKeyDerivationSettings) // GOOD

View File

@@ -26,7 +26,7 @@ final class Scrypt {
// Helper functions
func getConstantString() -> String {
"this string is constant"
"this string is constant" // $ Source
}
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]
let constantSalt: Array<UInt8> = [0x2a, 0x3a, 0x80, 0x05, 0xaf, 0x46, 0x58, 0x2d, 0x66, 0x52, 0x10, 0xae, 0x86, 0xd3, 0x8e, 0x8f] // $ Source
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) // BAD
let hkdfb2 = HKDF(password: randomArray, salt: constantStringSalt, info: randomArray, keyLength: 0, variant: variant) // BAD
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 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) // BAD
let pbkdf1b2 = PKCS5.PBKDF1(password: randomArray, salt: constantStringSalt, iterations: iterations, keyLength: 0) // BAD
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 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) // BAD
let pbkdf2b2 = PKCS5.PBKDF2(password: randomArray, salt: constantStringSalt, iterations: iterations, keyLength: 0) // BAD
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 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) // BAD
let scryptb2 = Scrypt(password: randomArray, salt: constantStringSalt, dkLen: 64, N: 16384, r: 8, p: 1) // BAD
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 scryptg1 = Scrypt(password: randomArray, salt: randomSalt, dkLen: 64, N: 16384, r: 8, p: 1) // GOOD
}

View File

@@ -1 +1,2 @@
queries/Security/CWE-916/InsufficientHashIterations.ql
query: queries/Security/CWE-916/InsufficientHashIterations.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -17,7 +17,7 @@ extension PKCS5 {
}
// Helper functions
func getLowIterationCount() -> Int { return 99999 }
func getLowIterationCount() -> Int { return 99999 } // $ Source
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) // BAD
let pbkdf1b2 = PKCS5.PBKDF1(password: randomArray, salt: randomArray, iterations: 80000, keyLength: 0) // BAD
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 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) // BAD
let pbkdf2b2 = PKCS5.PBKDF2(password: randomArray, salt: randomArray, iterations: 80000, keyLength: 0) // BAD
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 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
}