Compare commits

..

1 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
838d06c53f Fix changelog copy errors in change-notes and CHANGELOG.md files (codeql-cli-2.25.6) 2026-06-11 22:45:33 +02:00
64 changed files with 750 additions and 807 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, 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.
* 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.
## 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, 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.
* 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.

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 in 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 a 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 in 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 a minor point, added one more listed resource and added one more recommendation for things to check.

View File

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

View File

@@ -435,32 +435,6 @@ 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,18 +3,14 @@
| 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: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 |
| 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 |

View File

@@ -3,8 +3,6 @@
'bundle';// and this
'use server';
'use client';
'use memo';
'use no memo';
'use cache';
'use cache: remote';
'use cache: private';
@@ -20,8 +18,6 @@ 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 less fewer 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 fewer false 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 less fewer 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 fewer false positive results after these changes.

View File

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

View File

@@ -1,2 +1 @@
query: queries/Security/CWE-020/MissingRegexAnchor.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
queries/Security/CWE-020/MissingRegexAnchor.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) // $ Alert // BAD (missing anchor)
_ = try Regex("^a|b").firstMatch(in: input) // BAD (missing anchor)
_ = try Regex("a|^b").firstMatch(in: input)
_ = try Regex("^a|^b").firstMatch(in: input)
_ = try Regex("^a|b|c").firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex("^a|b|c").firstMatch(in: input) // BAD (missing anchor)
_ = try Regex("a|^b|c").firstMatch(in: input)
_ = try Regex("a|b|^c").firstMatch(in: input)
_ = try Regex("^a|^b|c").firstMatch(in: input)
_ = try Regex("(^a)|b").firstMatch(in: input)
_ = try Regex("^a|(b)").firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex("^a|(b)").firstMatch(in: input) // BAD (missing anchor)
_ = try Regex("^a|(^b)").firstMatch(in: input)
_ = try Regex("^(a)|(b)").firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex("^(a)|(b)").firstMatch(in: input) // BAD (missing anchor)
_ = try Regex("a|b$").firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex("a|b$").firstMatch(in: input) // BAD (missing anchor)
_ = try Regex("a$|b").firstMatch(in: input)
_ = try Regex("a$|b$").firstMatch(in: input)
_ = try Regex("a|b|c$").firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex("a|b|c$").firstMatch(in: input) // BAD (missing anchor)
_ = try Regex("a|b$|c").firstMatch(in: input)
_ = try Regex("a$|b|c").firstMatch(in: input)
_ = try Regex("a|b$|c$").firstMatch(in: input)
_ = try Regex("a|(b$)").firstMatch(in: input)
_ = try Regex("(a)|b$").firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex("(a)|b$").firstMatch(in: input) // BAD (missing anchor)
_ = try Regex("(a$)|b$").firstMatch(in: input)
_ = try Regex("(a)|(b)$").firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex("(a)|(b)$").firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^good.com|better.com"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex(#"^good\.com|better\.com"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex(#"^good\\.com|better\\.com"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex(#"^good\\\.com|better\\\.com"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex(#"^good\\\\.com|better\\\\.com"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex(#"^good.com|better.com"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^good\.com|better\.com"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^good\\.com|better\\.com"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^good\\\.com|better\\\.com"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^good\\\\.com|better\\\\.com"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex("^foo|bar|baz$").firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex("^foo|bar|baz$").firstMatch(in: input) // BAD (missing anchor)
_ = try Regex("^foo|%").firstMatch(in: input)
}
func realWorld(input: String) throws {
// real-world examples that have been anonymized a bit
// the following are bad:
_ = try Regex(#"(\.xxx)|(\.yyy)|(\.zzz)$"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex(#"(^left|right|center)\sbottom$"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex(#"\.xxx|\.yyy|\.zzz$"#).ignoresCase().firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex(#"\.xxx|\.yyy|\.zzz$"#).ignoresCase().firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex(#"\.xxx|\.yyy|zzz$"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex(#"^([A-Z]|xxx[XY]$)"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex(#"^(xxx yyy zzz)|(xxx yyy)"#).ignoresCase().firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex(#"^(xxx yyy zzz)|(xxx yyy)|(1st( xxx)? yyy)|xxx|1st"#).ignoresCase().firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex(#"^(xxx:)|(yyy:)|(zzz:)"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex(#"^(xxx?:)|(yyy:zzz\/)"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex(#"^@media|@page"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex(#"^\s*(xxx?|yyy|zzz):|xxx:yyy"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex(#"^click|mouse|touch"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex(#"^http://good\.com|http://better\.com"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex(#"^https?://good\.com|https?://better\.com"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex(#"^mouse|touch|click|contextmenu|drop|dragover|dragend"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex(#"^xxx:|yyy:"#).ignoresCase().firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex(#"_xxx|_yyy|_zzz$"#).firstMatch(in: input) // $ Alert // BAD (missing anchor)
_ = try Regex(#"(\.xxx)|(\.yyy)|(\.zzz)$"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"(^left|right|center)\sbottom$"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"\.xxx|\.yyy|\.zzz$"#).ignoresCase().firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"\.xxx|\.yyy|\.zzz$"#).ignoresCase().firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"\.xxx|\.yyy|zzz$"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^([A-Z]|xxx[XY]$)"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^(xxx yyy zzz)|(xxx yyy)"#).ignoresCase().firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^(xxx yyy zzz)|(xxx yyy)|(1st( xxx)? yyy)|xxx|1st"#).ignoresCase().firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^(xxx:)|(yyy:)|(zzz:)"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^(xxx?:)|(yyy:zzz\/)"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^@media|@page"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^\s*(xxx?|yyy|zzz):|xxx:yyy"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^click|mouse|touch"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^http://good\.com|http://better\.com"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^https?://good\.com|https?://better\.com"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^mouse|touch|click|contextmenu|drop|dragover|dragend"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^xxx:|yyy:"#).ignoresCase().firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"_xxx|_yyy|_zzz$"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"em|%$"#).firstMatch(in: input) // BAD (missing anchor) [NOT DETECTED] - not flagged at the moment due to the anchor not being for letters
// the following are MAYBE OK due to apparent complexity; not flagged

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) // $ Alert // BAD (missing anchor)
_ = try NSRegularExpression(pattern: "https?://good.com").matches(in: input, range: inputRange) // $ Alert // BAD (missing anchor)
_ = try NSRegularExpression(pattern: "^https?://good.com").matches(in: input, range: inputRange) // $ Alert // BAD (missing post-anchor)
_ = try NSRegularExpression(pattern: "(^https?://good1.com)|(^https?://good2.com)").matches(in: input, range: inputRange) // $ Alert // BAD (missing post-anchor)
_ = try NSRegularExpression(pattern: "(https?://good.com)|(^https?://goodie.com)").matches(in: input, range: inputRange) // $ Alert // BAD (missing anchor)
_ = try NSRegularExpression(pattern: "https?://good.com").matches(in: input, range: inputRange) // BAD (missing anchor)
_ = try NSRegularExpression(pattern: "https?://good.com").matches(in: input, range: inputRange) // BAD (missing anchor)
_ = try NSRegularExpression(pattern: "^https?://good.com").matches(in: input, range: inputRange) // BAD (missing post-anchor)
_ = try NSRegularExpression(pattern: "(^https?://good1.com)|(^https?://good2.com)").matches(in: input, range: inputRange) // BAD (missing post-anchor)
_ = try NSRegularExpression(pattern: "(https?://good.com)|(^https?://goodie.com)").matches(in: input, range: inputRange) // BAD (missing anchor)
_ = try NSRegularExpression(pattern: #"https?:\/\/good.com"#).matches(in: input, range: inputRange) // $ Alert // BAD (missing anchor)
_ = try NSRegularExpression(pattern: "https?://good.com").matches(in: input, range: inputRange) // $ Alert // BAD (missing anchor)
_ = try NSRegularExpression(pattern: #"https?:\/\/good.com"#).matches(in: input, range: inputRange) // BAD (missing anchor)
_ = try NSRegularExpression(pattern: "https?://good.com").matches(in: input, range: inputRange) // BAD (missing anchor)
if let _ = try NSRegularExpression(pattern: "https?://good.com").firstMatch(in: input, range: inputRange) { } // $ Alert // BAD (missing anchor)
if let _ = try NSRegularExpression(pattern: "https?://good.com").firstMatch(in: input, range: inputRange) { } // BAD (missing anchor)
let input2 = "something"
let input2Range = NSMakeRange(0, input2.utf16.count)
_ = try NSRegularExpression(pattern: "other").firstMatch(in: input2, range: input2Range) // OK
_ = try NSRegularExpression(pattern: "x.commissary").firstMatch(in: input2, range: input2Range) // OK
_ = try NSRegularExpression(pattern: #"https?://good.com"#).firstMatch(in: input, range: inputRange) // $ Alert // BAD (missing anchor)
_ = try NSRegularExpression(pattern: #"https?://good.com:8080"#).firstMatch(in: input, range: inputRange) // $ Alert // BAD (missing anchor)
_ = try NSRegularExpression(pattern: #"https?://good.com"#).firstMatch(in: input, range: inputRange) // BAD (missing anchor)
_ = try NSRegularExpression(pattern: #"https?://good.com:8080"#).firstMatch(in: input, range: inputRange) // BAD (missing anchor)
let trustedUrlRegexs = [
"https?://good.com", // $ Alert // BAD (missing anchor), referenced below
#"https?:\/\/good.com"#, // $ Alert // BAD (missing anchor), referenced below
"^https?://good.com" // $ Alert // BAD (missing post-anchor), referenced below
"https?://good.com", // BAD (missing anchor), referenced below
#"https?:\/\/good.com"#, // BAD (missing anchor), referenced below
"^https?://good.com" // BAD (missing post-anchor), referenced below
]
for trustedUrlRegex in trustedUrlRegexs {
if let _ = try NSRegularExpression(pattern: trustedUrlRegex).firstMatch(in: input, range: inputRange) { }
}
let trustedUrlRegexs2 = [
"https?://good.com", // $ Alert // BAD (missing anchor), referenced below
"https?://good.com", // BAD (missing anchor), referenced below
]
if let _ = try NSRegularExpression(pattern: trustedUrlRegexs2[0]).firstMatch(in: input, range: inputRange) { }
@@ -98,13 +98,13 @@ func tests(url: String, secure: Bool) throws {
for _ in notUsedUrlRegexs {
}
_ = try NSRegularExpression(pattern: #"https?:\/\/good.com\/([0-9]+)"#).matches(in: url, range: urlRange) // $ Alert // BAD (missing anchor)
_ = try NSRegularExpression(pattern: #"https?:\/\/good.com\/([0-9]+)"#).matches(in: url, range: urlRange) // BAD (missing anchor)
_ = try NSRegularExpression(pattern: "https://verygood.com/?id=" + #"https?:\/\/good.com\/([0-9]+)"#).matches(in: url, range: urlRange)[0] // OK
_ = try NSRegularExpression(pattern: "http" + (secure ? "s" : "") + "://" + "verygood.com/?id=" + #"https?:\/\/good.com\/([0-9]+)"#).matches(in: url, range: urlRange)[0] // OK
_ = try NSRegularExpression(pattern: "verygood.com/?id=" + #"https?:\/\/good.com\/([0-9]+)"#).matches(in: url, range: urlRange)[0] // OK
_ = try NSRegularExpression(pattern: #"\.com|\.org"#).matches(in: input, range: inputRange) // OK, has no domain name
_ = try NSRegularExpression(pattern: #"example\.com|whatever"#).matches(in: input, range: inputRange) // $ Alert // OK, the other disjunction doesn't match a hostname [FALSE POSITIVE]
_ = try NSRegularExpression(pattern: #"example\.com|whatever"#).matches(in: input, range: inputRange) // OK, the other disjunction doesn't match a hostname [FALSE POSITIVE]
// tests for the `isLineAnchoredHostnameRegExp` case

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) // $ Alert // BAD (missing anchor)
_ = try Regex(#"^http://example.com"#).firstMatch(in: tainted) // BAD (missing anchor)
_ = try Regex(#"^http://test\.example\.com/"#).firstMatch(in: tainted) // GOOD
_ = try Regex(#"^http://test\.example.com/"#).firstMatch(in: tainted) // GOOD (only '.' here gives a valid top-level domain)
_ = try Regex(#"^http://test\.example.com"#).firstMatch(in: tainted) // $ Alert // BAD (missing anchor)
_ = try Regex(#"^http://test.example.com/"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
_ = try Regex(#"^http://test\.example.com"#).firstMatch(in: tainted) // BAD (missing anchor)
_ = try Regex(#"^http://test.example.com/"#).firstMatch(in: tainted) // BAD (incomplete hostname)
_ = try Regex(#"^http://test[.]example[.]com/"#).firstMatch(in: tainted) // GOOD (alternative method of escaping)
_ = try Regex(#"^http://test.example.net/"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
_ = try Regex(#"^http://test.(example-a|example-b).com/"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
_ = try Regex(#"^http://(.+).example.com/"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname x 2)
_ = try Regex(#"^http://test.example.net/"#).firstMatch(in: tainted) // BAD (incomplete hostname)
_ = try Regex(#"^http://test.(example-a|example-b).com/"#).firstMatch(in: tainted) // BAD (incomplete hostname)
_ = try Regex(#"^http://(.+).example.com/"#).firstMatch(in: tainted) // BAD (incomplete hostname x 2)
_ = try Regex(#"^http://(\.+)\.example.com/"#).firstMatch(in: tainted) // GOOD
_ = try Regex(#"^http://(?:.+)\.test\.example.com/"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
_ = try Regex(#"^http://test.example.com/(?:.*)"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
_ = try Regex(#"^(.+\.(?:example-a|example-b)\.com)/"#).firstMatch(in: tainted) // $ Alert // BAD (missing anchor)
_ = try Regex(#"^(https?:)?//((service|www).)?example.com(?=$|/)"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
_ = try Regex(#"^(http|https)://www.example.com/p/f/"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
_ = try Regex(#"^(http://sub.example.com/)"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
_ = try Regex(#"^https?://api.example.com/"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
_ = try Regex(#"^http://(?:.+)\.test\.example.com/"#).firstMatch(in: tainted) // BAD (incomplete hostname)
_ = try Regex(#"^http://test.example.com/(?:.*)"#).firstMatch(in: tainted) // BAD (incomplete hostname)
_ = try Regex(#"^(.+\.(?:example-a|example-b)\.com)/"#).firstMatch(in: tainted) // BAD (missing anchor)
_ = try Regex(#"^(https?:)?//((service|www).)?example.com(?=$|/)"#).firstMatch(in: tainted) // BAD (incomplete hostname)
_ = try Regex(#"^(http|https)://www.example.com/p/f/"#).firstMatch(in: tainted) // BAD (incomplete hostname)
_ = try Regex(#"^(http://sub.example.com/)"#).firstMatch(in: tainted) // BAD (incomplete hostname)
_ = try Regex(#"^https?://api.example.com/"#).firstMatch(in: tainted) // BAD (incomplete hostname)
_ = try Regex(#"^http[s]?://?sub1\.sub2\.example\.com/f/(.+)"#).firstMatch(in: tainted) // GOOD (it has a capture group after the TLD, so should be ignored)
_ = try Regex(#"^https://[a-z]*.example.com$"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
_ = try Regex(#"^(example.dev|example.com)"#).firstMatch(in: tainted) // $ Alert // GOOD (any extended hostname wouldn't be included in the capture group) [FALSE POSITIVE]
_ = try Regex(#"^protos?://(localhost|.+.example.net|.+.example-a.com|.+.example-b.com|.+.example.internal)"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname x3, missing anchor x 1)
_ = try Regex(#"^https://[a-z]*.example.com$"#).firstMatch(in: tainted) // BAD (incomplete hostname)
_ = try Regex(#"^(example.dev|example.com)"#).firstMatch(in: tainted) // GOOD (any extended hostname wouldn't be included in the capture group) [FALSE POSITIVE]
_ = try Regex(#"^protos?://(localhost|.+.example.net|.+.example-a.com|.+.example-b.com|.+.example.internal)"#).firstMatch(in: tainted) // BAD (incomplete hostname x3, missing anchor x 1)
_ = try Regex(#"^http://(..|...)\.example\.com/index\.html"#).firstMatch(in: tainted) // GOOD (wildcards are intentional)
_ = try Regex(#"^http://.\.example\.com/index\.html"#).firstMatch(in: tainted) // GOOD (the wildcard is intentional)
_ = try Regex(#"^(foo.example\.com|whatever)$"#).firstMatch(in: tainted) // $ Alert // DUBIOUS (one disjunction doesn't even look like a hostname) [DETECTED incomplete hostname, missing anchor]
_ = try Regex(#"^(foo.example\.com|whatever)$"#).firstMatch(in: tainted) // DUBIOUS (one disjunction doesn't even look like a hostname) [DETECTED incomplete hostname, missing anchor]
_ = try Regex(#"^test.example.com$"#).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
_ = try Regex(#"test.example.com"#).wholeMatch(in: tainted) // $ Alert // BAD (incomplete hostname, missing anchor)
_ = try Regex(#"^test.example.com$"#).firstMatch(in: tainted) // BAD (incomplete hostname)
_ = try Regex(#"test.example.com"#).wholeMatch(in: tainted) // BAD (incomplete hostname, missing anchor)
_ = try Regex(id(id(id(#"test.example.com$"#)))).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
_ = try Regex(id(id(id(#"test.example.com$"#)))).firstMatch(in: tainted) // BAD (incomplete hostname)
let hostname = #"test.example.com$"# // BAD (incomplete hostname) [NOT DETECTED]
_ = try Regex("\(hostname)").firstMatch(in: tainted)
var domain = MyDomain("")
domain.hostname = #"test.example.com$"# // $ Alert // BAD (incomplete hostname)
domain.hostname = #"test.example.com$"# // BAD (incomplete hostname)
_ = try Regex(domain.hostname).firstMatch(in: tainted)
func convert1(_ domain: MyDomain) throws -> Regex<AnyRegexOutput> {
return try Regex(domain.hostname)
}
_ = try convert1(MyDomain(#"test.example.com$"#)).firstMatch(in: tainted) // $ Alert // BAD (incomplete hostname)
_ = try convert1(MyDomain(#"test.example.com$"#)).firstMatch(in: tainted) // BAD (incomplete hostname)
let domains = [ MyDomain(#"test.example.com$"#) ] // BAD (incomplete hostname) [NOT DETECTED]
func convert2(_ domain: MyDomain) throws -> Regex<AnyRegexOutput> {

View File

@@ -1,2 +1 @@
query: experimental/Security/CWE-022/UnsafeUnpack.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
experimental/Security/CWE-022/UnsafeUnpack.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) // $ Source
try Data(contentsOf: remoteURL, options: []).write(to: source)
do {
try Zip.unzipFile(source, destination: destination, overwrite: true, password: nil) // $ Alert
try Zip.unzipFile(source, destination: destination, overwrite: true, password: nil) // BAD
let fileManager = FileManager()
try fileManager.unzipItem(at: source, to: destination) // $ Alert
try fileManager.unzipItem(at: source, to: destination) // BAD
} catch {
print("Error: \(error)")
}

View File

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

View File

@@ -91,7 +91,7 @@ func getRemoteData() -> String {
let url = URL(string: "http://example.com/")
do
{
return try String(contentsOf: url!) // $ Source
return try String(contentsOf: url!)
} catch {
return ""
}
@@ -100,13 +100,13 @@ func getRemoteData() -> String {
func testSimpleFlows() {
let webview = UIWebView()
webview.loadHTMLString(try! String(contentsOf: URL(string: "http://example.com/")!), baseURL: nil) // $ Alert
webview.loadHTMLString(try! String(contentsOf: URL(string: "http://example.com/")!), baseURL: nil) // BAD
let data = try! String(contentsOf: URL(string: "http://example.com/")!) // $ Source
webview.loadHTMLString(data, baseURL: nil) // $ Alert
let data = try! String(contentsOf: URL(string: "http://example.com/")!)
webview.loadHTMLString(data, baseURL: nil) // BAD
let url = URL(string: "http://example.com/")
webview.loadHTMLString(try! String(contentsOf: url!), baseURL: nil) // $ Alert
webview.loadHTMLString(try! String(contentsOf: url!), baseURL: nil) // BAD
}
func testUIWebView() {
@@ -117,14 +117,14 @@ func testUIWebView() {
let remoteString = getRemoteData()
webview.loadHTMLString(localString, baseURL: nil) // GOOD: the HTML data is local
webview.loadHTMLString(getRemoteData(), baseURL: nil) // $ Alert // BAD: HTML contains remote input, may access local secrets
webview.loadHTMLString(remoteString, baseURL: nil) // $ Alert
webview.loadHTMLString(getRemoteData(), baseURL: nil) // BAD: HTML contains remote input, may access local secrets
webview.loadHTMLString(remoteString, baseURL: nil) // BAD
webview.loadHTMLString("<html>" + localStringFragment + "</html>", baseURL: nil) // GOOD: the HTML data is local
webview.loadHTMLString("<html>" + remoteString + "</html>", baseURL: nil) // $ Alert
webview.loadHTMLString("<html>" + remoteString + "</html>", baseURL: nil) // BAD
webview.loadHTMLString("<html>\(localStringFragment)</html>", baseURL: nil) // GOOD: the HTML data is local
webview.loadHTMLString("<html>\(remoteString)</html>", baseURL: nil) // $ Alert
webview.loadHTMLString("<html>\(remoteString)</html>", baseURL: nil) // BAD
let localSafeURL = URL(string: "about:blank")
let localURL = URL(string: "http://example.com/")
@@ -136,9 +136,9 @@ func testUIWebView() {
webview.loadHTMLString(localString, baseURL: localURL!) // GOOD: a presumed safe baseURL is specified
webview.loadHTMLString(remoteString, baseURL: localURL!) // GOOD: a presumed safe baseURL is specified
webview.loadHTMLString(localString, baseURL: remoteURL!) // GOOD: the HTML data is local
webview.loadHTMLString(remoteString, baseURL: remoteURL!) // $ Alert
webview.loadHTMLString(remoteString, baseURL: remoteURL!) // BAD
webview.loadHTMLString(localString, baseURL: remoteURL2!) // GOOD: the HTML data is local
webview.loadHTMLString(remoteString, baseURL: remoteURL2!) // $ Alert
webview.loadHTMLString(remoteString, baseURL: remoteURL2!) // BAD
let localRequest = URLRequest(url: localURL!)
let remoteRequest = URLRequest(url: remoteURL!)
@@ -151,7 +151,7 @@ func testUIWebView() {
webview.load(localData, mimeType: "text/html", textEncodingName: "utf-8", baseURL: localSafeURL!) // GOOD: the data is local
webview.load(remoteData, mimeType: "text/html", textEncodingName: "utf-8", baseURL: localSafeURL!) // GOOD: a safe baseURL is specified
webview.load(localData, mimeType: "text/html", textEncodingName: "utf-8", baseURL: remoteURL!) // GOOD: the HTML data is local
webview.load(remoteData, mimeType: "text/html", textEncodingName: "utf-8", baseURL: remoteURL!) // $ Alert
webview.load(remoteData, mimeType: "text/html", textEncodingName: "utf-8", baseURL: remoteURL!) // BAD
}
func testWKWebView() {
@@ -164,14 +164,14 @@ func testWKWebView() {
let remoteString = getRemoteData()
webview.loadHTMLString(localString, baseURL: nil) // GOOD: the HTML data is local
webview.loadHTMLString(getRemoteData(), baseURL: nil) // $ Alert
webview.loadHTMLString(remoteString, baseURL: nil) // $ Alert
webview.loadHTMLString(getRemoteData(), baseURL: nil) // BAD
webview.loadHTMLString(remoteString, baseURL: nil) // BAD
webview.loadHTMLString("<html>" + localStringFragment + "</html>", baseURL: nil) // GOOD: the HTML data is local
webview.loadHTMLString("<html>" + remoteString + "</html>", baseURL: nil) // $ Alert
webview.loadHTMLString("<html>" + remoteString + "</html>", baseURL: nil) // BAD
webview.loadHTMLString("<html>\(localStringFragment)</html>", baseURL: nil) // GOOD: the HTML data is local
webview.loadHTMLString("<html>\(remoteString)</html>", baseURL: nil) // $ Alert
webview.loadHTMLString("<html>\(remoteString)</html>", baseURL: nil) // BAD
let localSafeURL = URL(string: "about:blank")
let localURL = URL(string: "http://example.com/")
@@ -183,9 +183,9 @@ func testWKWebView() {
webview.loadHTMLString(localString, baseURL: localURL!) // GOOD: a presumed safe baseURL is specified
webview.loadHTMLString(remoteString, baseURL: localURL!) // GOOD: a presumed safe baseURL is specified
webview.loadHTMLString(localString, baseURL: remoteURL!) // GOOD: the HTML data is local
webview.loadHTMLString(remoteString, baseURL: remoteURL!) // $ Alert
webview.loadHTMLString(remoteString, baseURL: remoteURL!) // BAD
webview.loadHTMLString(localString, baseURL: remoteURL2!) // GOOD: the HTML data is local
webview.loadHTMLString(remoteString, baseURL: remoteURL2!) // $ Alert
webview.loadHTMLString(remoteString, baseURL: remoteURL2!) // BAD
let localRequest = URLRequest(url: localURL!)
let remoteRequest = URLRequest(url: remoteURL!)
@@ -198,7 +198,7 @@ func testWKWebView() {
webview.load(localData, mimeType: "text/html", characterEncodingName: "utf-8", baseURL: localSafeURL!) // GOOD: the data is local
webview.load(remoteData, mimeType: "text/html", characterEncodingName: "utf-8", baseURL: localSafeURL!) // GOOD: a safe baseURL is specified
webview.load(localData, mimeType: "text/html", characterEncodingName: "utf-8", baseURL: remoteURL!) // GOOD: the HTML data is local
webview.load(remoteData, mimeType: "text/html", characterEncodingName: "utf-8", baseURL: remoteURL!) // $ Alert
webview.load(remoteData, mimeType: "text/html", characterEncodingName: "utf-8", baseURL: remoteURL!) // BAD
}
func testQHelpExamples() {
@@ -207,7 +207,7 @@ func testQHelpExamples() {
// ...
webview.loadHTMLString(htmlData, baseURL: nil) // $ Alert
webview.loadHTMLString(htmlData, baseURL: nil) // BAD
webview.loadHTMLString(htmlData, baseURL: URL(string: "about:blank")) // GOOD
}

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/")!) // $ Source
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
let _ = database.allStatements(sql: remoteString) // $ Alert
let _ = database.allStatements(sql: remoteString) // BAD
let _ = database.allStatements(sql: localString) // GOOD
let _ = database.allStatements(sql: remoteString, arguments: nil) // $ Alert
let _ = database.allStatements(sql: remoteString, arguments: nil) // BAD
let _ = database.allStatements(sql: localString, arguments: nil) // GOOD
let _ = database.cachedStatement(sql: remoteString) // $ Alert
let _ = database.cachedStatement(sql: remoteString) // BAD
let _ = database.cachedStatement(sql: localString) // GOOD
let _ = database.internalCachedStatement(sql: remoteString) // $ Alert
let _ = database.internalCachedStatement(sql: remoteString) // BAD
let _ = database.internalCachedStatement(sql: localString) // GOOD
database.execute(sql: remoteString) // $ Alert
database.execute(sql: remoteString) // BAD
database.execute(sql: localString) // GOOD
database.execute(sql: remoteString, arguments: StatementArguments()) // $ Alert
database.execute(sql: remoteString, arguments: StatementArguments()) // BAD
database.execute(sql: localString, arguments: StatementArguments()) // GOOD
let _ = database.makeStatement(sql: remoteString) // $ Alert
let _ = database.makeStatement(sql: remoteString) // BAD
let _ = database.makeStatement(sql: localString) // GOOD
let _ = database.makeStatement(sql: remoteString, prepFlags: 0) // $ Alert
let _ = database.makeStatement(sql: remoteString, prepFlags: 0) // BAD
let _ = database.makeStatement(sql: localString, prepFlags: 0) // GOOD
}
func testSqlRequest() throws {
let localString = "user"
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
let _ = SQLRequest(stringLiteral: remoteString) // $ Alert
let _ = SQLRequest(stringLiteral: remoteString) // BAD
let _ = SQLRequest(stringLiteral: localString) // GOOD
let _ = SQLRequest(unicodeScalarLiteral: remoteString) // $ Alert
let _ = SQLRequest(unicodeScalarLiteral: remoteString) // BAD
let _ = SQLRequest(unicodeScalarLiteral: localString) // GOOD
let _ = SQLRequest(extendedGraphemeClusterLiteral: remoteString) // $ Alert
let _ = SQLRequest(extendedGraphemeClusterLiteral: remoteString) // BAD
let _ = SQLRequest(extendedGraphemeClusterLiteral: localString) // GOOD
let _ = SQLRequest(stringInterpolation: remoteString) // $ Alert
let _ = SQLRequest(stringInterpolation: remoteString) // BAD
let _ = SQLRequest(stringInterpolation: localString) // GOOD
let _ = SQLRequest(sql: remoteString) // $ Alert
let _ = SQLRequest(sql: remoteString, arguments: StatementArguments()) // $ Alert
let _ = SQLRequest(sql: remoteString, arguments: StatementArguments(), adapter: nil) // $ Alert
let _ = SQLRequest(sql: remoteString, arguments: StatementArguments(), cached: false) // $ Alert
let _ = SQLRequest(sql: remoteString, arguments: StatementArguments(), adapter: nil, cached: false) // $ Alert
let _ = SQLRequest(sql: remoteString, adapter: nil) // $ Alert
let _ = SQLRequest(sql: remoteString, adapter: nil, cached: false) // $ Alert
let _ = SQLRequest(sql: remoteString, cached: false) // $ Alert
let _ = SQLRequest(sql: remoteString) // BAD
let _ = SQLRequest(sql: remoteString, arguments: StatementArguments()) // BAD
let _ = SQLRequest(sql: remoteString, arguments: StatementArguments(), adapter: nil) // BAD
let _ = SQLRequest(sql: remoteString, arguments: StatementArguments(), cached: false) // BAD
let _ = SQLRequest(sql: remoteString, arguments: StatementArguments(), adapter: nil, cached: false) // BAD
let _ = SQLRequest(sql: remoteString, adapter: nil) // BAD
let _ = SQLRequest(sql: remoteString, adapter: nil, cached: false) // BAD
let _ = SQLRequest(sql: remoteString, cached: false) // BAD
let _ = SQLRequest(sql: localString) // GOOD
let _ = SQLRequest(sql: localString, arguments: StatementArguments()) // GOOD
let _ = SQLRequest(sql: localString, arguments: StatementArguments(), adapter: nil) // GOOD
@@ -161,15 +161,15 @@ func testSqlRequest() throws {
func testSql() throws {
let localString = "user"
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
let _ = SQL(stringLiteral: remoteString) // $ Alert
let _ = SQL(unicodeScalarLiteral: remoteString) // $ Alert
let _ = SQL(extendedGraphemeClusterLiteral: remoteString) // $ Alert
let _ = SQL(stringInterpolation: remoteString) // $ Alert
let _ = SQL(sql: remoteString) // $ Alert
let _ = SQL(stringLiteral: remoteString) // BAD
let _ = SQL(unicodeScalarLiteral: remoteString) // BAD
let _ = SQL(extendedGraphemeClusterLiteral: remoteString) // BAD
let _ = SQL(stringInterpolation: remoteString) // BAD
let _ = SQL(sql: remoteString) // BAD
let sql1 = SQL(stringLiteral: "")
sql1.append(sql: remoteString) // $ Alert
sql1.append(sql: remoteString) // BAD
let _ = SQL(stringLiteral: localString) // GOOD
let _ = SQL(unicodeScalarLiteral: localString) // GOOD
@@ -182,34 +182,34 @@ func testSql() throws {
func test(tableDefinition: TableDefinition) throws {
let localString = "user"
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
tableDefinition.column(sql: remoteString) // $ Alert
tableDefinition.column(sql: remoteString) // BAD
tableDefinition.column(sql: localString) // GOOD
tableDefinition.check(sql: remoteString) // $ Alert
tableDefinition.check(sql: remoteString) // BAD
tableDefinition.check(sql: localString) // GOOD
tableDefinition.constraint(sql: remoteString) // $ Alert
tableDefinition.constraint(sql: remoteString) // BAD
tableDefinition.constraint(sql: localString) // GOOD
}
func test(tableAlteration: TableAlteration) throws {
let localString = "user"
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
tableAlteration.addColumn(sql: remoteString) // $ Alert
tableAlteration.addColumn(sql: remoteString) // BAD
tableAlteration.addColumn(sql: localString) // GOOD
}
func test(columnDefinition: ColumnDefinition) throws {
let localString = "user"
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
let _ = columnDefinition.check(sql: remoteString) // $ Alert
let _ = columnDefinition.defaults(sql: remoteString) // $ Alert
let _ = columnDefinition.generatedAs(sql: remoteString) // $ Alert
let _ = columnDefinition.generatedAs(sql: remoteString, .virtual) // $ Alert
let _ = columnDefinition.check(sql: remoteString) // BAD
let _ = columnDefinition.defaults(sql: remoteString) // BAD
let _ = columnDefinition.generatedAs(sql: remoteString) // BAD
let _ = columnDefinition.generatedAs(sql: remoteString, .virtual) // BAD
let _ = columnDefinition.check(sql: localString) // GOOD
let _ = columnDefinition.defaults(sql: localString) // GOOD
@@ -219,67 +219,67 @@ func test(columnDefinition: ColumnDefinition) throws {
func testTableRecord() throws {
let localString = "user"
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
let _ = TableRecord.select(sql: remoteString) // $ Alert
let _ = TableRecord.select(sql: remoteString, arguments: StatementArguments()) // $ Alert
let _ = TableRecord.select(sql: remoteString) // BAD
let _ = TableRecord.select(sql: remoteString, arguments: StatementArguments()) // BAD
let _ = TableRecord.select(sql: localString) // GOOD
let _ = TableRecord.select(sql: localString, arguments: StatementArguments()) // GOOD
let _ = TableRecord.filter(sql: remoteString) // $ Alert
let _ = TableRecord.filter(sql: remoteString, arguments: StatementArguments()) // $ Alert
let _ = TableRecord.filter(sql: remoteString) // BAD
let _ = TableRecord.filter(sql: remoteString, arguments: StatementArguments()) // BAD
let _ = TableRecord.filter(sql: localString) // GOOD
let _ = TableRecord.filter(sql: localString, arguments: StatementArguments()) // GOOD
let _ = TableRecord.order(sql: remoteString) // $ Alert
let _ = TableRecord.order(sql: remoteString, arguments: StatementArguments()) // $ Alert
let _ = TableRecord.order(sql: remoteString) // BAD
let _ = TableRecord.order(sql: remoteString, arguments: StatementArguments()) // BAD
let _ = TableRecord.order(sql: localString) // GOOD
let _ = TableRecord.order(sql: localString, arguments: StatementArguments()) // GOOD
}
func test(statementCache: StatementCache) throws {
let localString = "user"
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
let _ = statementCache.statement(remoteString) // $ Alert
let _ = statementCache.statement(remoteString) // BAD
let _ = statementCache.statement(localString) // GOOD
}
func test(row: Row, stmt: Statement) throws {
let localString = "user"
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
row.fetchCursor(stmt, sql: remoteString) // $ Alert
row.fetchCursor(stmt, sql: remoteString, arguments: StatementArguments()) // $ Alert
row.fetchCursor(stmt, sql: remoteString, adapter: nil) // $ Alert
row.fetchCursor(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // $ Alert
row.fetchCursor(stmt, sql: remoteString) // BAD
row.fetchCursor(stmt, sql: remoteString, arguments: StatementArguments()) // BAD
row.fetchCursor(stmt, sql: remoteString, adapter: nil) // BAD
row.fetchCursor(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // BAD
row.fetchCursor(stmt, sql: localString) // GOOD
row.fetchCursor(stmt, sql: localString, arguments: StatementArguments()) // GOOD
row.fetchCursor(stmt, sql: localString, adapter: nil) // GOOD
row.fetchCursor(stmt, sql: localString, arguments: StatementArguments(), adapter: nil) // GOOD
row.fetchAll(stmt, sql: remoteString) // $ Alert
row.fetchAll(stmt, sql: remoteString, arguments: StatementArguments()) // $ Alert
row.fetchAll(stmt, sql: remoteString, adapter: nil) // $ Alert
row.fetchAll(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // $ Alert
row.fetchAll(stmt, sql: remoteString) // BAD
row.fetchAll(stmt, sql: remoteString, arguments: StatementArguments()) // BAD
row.fetchAll(stmt, sql: remoteString, adapter: nil) // BAD
row.fetchAll(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // BAD
row.fetchAll(stmt, sql: localString) // GOOD
row.fetchAll(stmt, sql: localString, arguments: StatementArguments()) // GOOD
row.fetchAll(stmt, sql: localString, adapter: nil) // GOOD
row.fetchAll(stmt, sql: localString, arguments: StatementArguments(), adapter: nil) // GOOD
row.fetchOne(stmt, sql: remoteString) // $ Alert
row.fetchOne(stmt, sql: remoteString, arguments: StatementArguments()) // $ Alert
row.fetchOne(stmt, sql: remoteString, adapter: nil) // $ Alert
row.fetchOne(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // $ Alert
row.fetchOne(stmt, sql: remoteString) // BAD
row.fetchOne(stmt, sql: remoteString, arguments: StatementArguments()) // BAD
row.fetchOne(stmt, sql: remoteString, adapter: nil) // BAD
row.fetchOne(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // BAD
row.fetchOne(stmt, sql: localString) // GOOD
row.fetchOne(stmt, sql: localString, arguments: StatementArguments()) // GOOD
row.fetchOne(stmt, sql: localString, adapter: nil) // GOOD
row.fetchOne(stmt, sql: localString, arguments: StatementArguments(), adapter: nil) // GOOD
row.fetchSet(stmt, sql: remoteString) // $ Alert
row.fetchSet(stmt, sql: remoteString, arguments: StatementArguments()) // $ Alert
row.fetchSet(stmt, sql: remoteString, adapter: nil) // $ Alert
row.fetchSet(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // $ Alert
row.fetchSet(stmt, sql: remoteString) // BAD
row.fetchSet(stmt, sql: remoteString, arguments: StatementArguments()) // BAD
row.fetchSet(stmt, sql: remoteString, adapter: nil) // BAD
row.fetchSet(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // BAD
row.fetchSet(stmt, sql: localString) // GOOD
row.fetchSet(stmt, sql: localString, arguments: StatementArguments()) // GOOD
row.fetchSet(stmt, sql: localString, adapter: nil) // GOOD
@@ -288,39 +288,39 @@ func test(row: Row, stmt: Statement) throws {
func test(databaseValueConvertible: DatabaseValueConvertible, stmt: Statement) throws {
let localString = "user"
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
databaseValueConvertible.fetchCursor(stmt, sql: remoteString) // $ Alert
databaseValueConvertible.fetchCursor(stmt, sql: remoteString, arguments: StatementArguments()) // $ Alert
databaseValueConvertible.fetchCursor(stmt, sql: remoteString, adapter: nil) // $ Alert
databaseValueConvertible.fetchCursor(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // $ Alert
databaseValueConvertible.fetchCursor(stmt, sql: remoteString) // BAD
databaseValueConvertible.fetchCursor(stmt, sql: remoteString, arguments: StatementArguments()) // BAD
databaseValueConvertible.fetchCursor(stmt, sql: remoteString, adapter: nil) // BAD
databaseValueConvertible.fetchCursor(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // BAD
databaseValueConvertible.fetchCursor(stmt, sql: localString) // GOOD
databaseValueConvertible.fetchCursor(stmt, sql: localString, arguments: StatementArguments()) // GOOD
databaseValueConvertible.fetchCursor(stmt, sql: localString, adapter: nil) // GOOD
databaseValueConvertible.fetchCursor(stmt, sql: localString, arguments: StatementArguments(), adapter: nil) // GOOD
databaseValueConvertible.fetchAll(stmt, sql: remoteString) // $ Alert
databaseValueConvertible.fetchAll(stmt, sql: remoteString, arguments: StatementArguments()) // $ Alert
databaseValueConvertible.fetchAll(stmt, sql: remoteString, adapter: nil) // $ Alert
databaseValueConvertible.fetchAll(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // $ Alert
databaseValueConvertible.fetchAll(stmt, sql: remoteString) // BAD
databaseValueConvertible.fetchAll(stmt, sql: remoteString, arguments: StatementArguments()) // BAD
databaseValueConvertible.fetchAll(stmt, sql: remoteString, adapter: nil) // BAD
databaseValueConvertible.fetchAll(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // BAD
databaseValueConvertible.fetchAll(stmt, sql: localString) // GOOD
databaseValueConvertible.fetchAll(stmt, sql: localString, arguments: StatementArguments()) // GOOD
databaseValueConvertible.fetchAll(stmt, sql: localString, adapter: nil) // GOOD
databaseValueConvertible.fetchAll(stmt, sql: localString, arguments: StatementArguments(), adapter: nil) // GOOD
databaseValueConvertible.fetchOne(stmt, sql: remoteString) // $ Alert
databaseValueConvertible.fetchOne(stmt, sql: remoteString, arguments: StatementArguments()) // $ Alert
databaseValueConvertible.fetchOne(stmt, sql: remoteString, adapter: nil) // $ Alert
databaseValueConvertible.fetchOne(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // $ Alert
databaseValueConvertible.fetchOne(stmt, sql: remoteString) // BAD
databaseValueConvertible.fetchOne(stmt, sql: remoteString, arguments: StatementArguments()) // BAD
databaseValueConvertible.fetchOne(stmt, sql: remoteString, adapter: nil) // BAD
databaseValueConvertible.fetchOne(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // BAD
databaseValueConvertible.fetchOne(stmt, sql: localString) // GOOD
databaseValueConvertible.fetchOne(stmt, sql: localString, arguments: StatementArguments()) // GOOD
databaseValueConvertible.fetchOne(stmt, sql: localString, adapter: nil) // GOOD
databaseValueConvertible.fetchOne(stmt, sql: localString, arguments: StatementArguments(), adapter: nil) // GOOD
databaseValueConvertible.fetchSet(stmt, sql: remoteString) // $ Alert
databaseValueConvertible.fetchSet(stmt, sql: remoteString, arguments: StatementArguments()) // $ Alert
databaseValueConvertible.fetchSet(stmt, sql: remoteString, adapter: nil) // $ Alert
databaseValueConvertible.fetchSet(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // $ Alert
databaseValueConvertible.fetchSet(stmt, sql: remoteString) // BAD
databaseValueConvertible.fetchSet(stmt, sql: remoteString, arguments: StatementArguments()) // BAD
databaseValueConvertible.fetchSet(stmt, sql: remoteString, adapter: nil) // BAD
databaseValueConvertible.fetchSet(stmt, sql: remoteString, arguments: StatementArguments(), adapter: nil) // BAD
databaseValueConvertible.fetchSet(stmt, sql: localString) // GOOD
databaseValueConvertible.fetchSet(stmt, sql: localString, arguments: StatementArguments()) // GOOD
databaseValueConvertible.fetchSet(stmt, sql: localString, adapter: nil) // GOOD
@@ -329,26 +329,26 @@ func test(databaseValueConvertible: DatabaseValueConvertible, stmt: Statement) t
func testSqlStatementCursor(database: Database) throws {
let localString = "user"
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
let _ = SQLStatementCursor(database: database, sql: remoteString, arguments: StatementArguments()) // $ Alert
let _ = SQLStatementCursor(database: database, sql: remoteString, arguments: StatementArguments(), prepFlags: 0) // $ Alert
let _ = SQLStatementCursor(database: database, sql: remoteString, arguments: StatementArguments()) // BAD
let _ = SQLStatementCursor(database: database, sql: remoteString, arguments: StatementArguments(), prepFlags: 0) // BAD
let _ = SQLStatementCursor(database: database, sql: localString, arguments: StatementArguments()) // GOOD
let _ = SQLStatementCursor(database: database, sql: localString, arguments: StatementArguments(), prepFlags: 0) // GOOD
}
func testCommonTableExpression() throws {
let localString = "user"
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!) // $ Source
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
let _ = CommonTableExpression(named: "", sql: remoteString) // $ Alert
let _ = CommonTableExpression(named: "", sql: remoteString, arguments: StatementArguments()) // $ Alert
let _ = CommonTableExpression(named: "", columns: [""], sql: remoteString) // $ Alert
let _ = CommonTableExpression(named: "", columns: [""], sql: remoteString, arguments: StatementArguments()) // $ Alert
let _ = CommonTableExpression(recursive: false, named: "", sql: remoteString) // $ Alert
let _ = CommonTableExpression(recursive: false, named: "", columns: [""], sql: remoteString) // $ Alert
let _ = CommonTableExpression(recursive: false, named: "", sql: remoteString, arguments: StatementArguments()) // $ Alert
let _ = CommonTableExpression(recursive: false, named: "", columns: [""], sql: remoteString, arguments: StatementArguments()) // $ Alert
let _ = CommonTableExpression(named: "", sql: remoteString) // BAD
let _ = CommonTableExpression(named: "", sql: remoteString, arguments: StatementArguments()) // BAD
let _ = CommonTableExpression(named: "", columns: [""], sql: remoteString) // BAD
let _ = CommonTableExpression(named: "", columns: [""], sql: remoteString, arguments: StatementArguments()) // BAD
let _ = CommonTableExpression(recursive: false, named: "", sql: remoteString) // BAD
let _ = CommonTableExpression(recursive: false, named: "", columns: [""], sql: remoteString) // BAD
let _ = CommonTableExpression(recursive: false, named: "", sql: remoteString, arguments: StatementArguments()) // BAD
let _ = CommonTableExpression(recursive: false, named: "", columns: [""], sql: remoteString, arguments: StatementArguments()) // BAD
let _ = CommonTableExpression(named: "", sql: localString) // GOOD
let _ = CommonTableExpression(named: "", sql: localString, arguments: StatementArguments()) // GOOD
let _ = CommonTableExpression(named: "", columns: [""], sql: localString) // GOOD

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/")!) // $ Source
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
let remoteNumber = Int(remoteString) ?? 0
let unsafeQuery1 = remoteString
@@ -70,9 +70,9 @@ func test_sqlite_swift_api(db: Connection) throws {
// --- execute ---
try db.execute(unsafeQuery1) // $ Alert
try db.execute(unsafeQuery2) // $ Alert
try db.execute(unsafeQuery3) // $ Alert
try db.execute(unsafeQuery1) // BAD
try db.execute(unsafeQuery2) // BAD
try db.execute(unsafeQuery3) // BAD
try db.execute(safeQuery1) // GOOD
try db.execute(safeQuery2) // GOOD
@@ -80,7 +80,7 @@ func test_sqlite_swift_api(db: Connection) throws {
let varQuery = "SELECT * FROM users WHERE username=?"
let stmt1 = try db.prepare(unsafeQuery3) // $ Alert
let stmt1 = try db.prepare(unsafeQuery3) // BAD
try stmt1.run()
let stmt2 = try db.prepare(varQuery, localString) // GOOD
@@ -92,31 +92,31 @@ func test_sqlite_swift_api(db: Connection) throws {
let stmt4 = try Statement(db, localString) // GOOD
try stmt4.run()
let stmt5 = try Statement(db, remoteString) // $ Alert
let stmt5 = try Statement(db, remoteString) // BAD
try stmt5.run()
// --- more variants ---
let stmt6 = try db.prepare(unsafeQuery1, "") // $ Alert
let stmt6 = try db.prepare(unsafeQuery1, "") // BAD
try stmt6.run()
let stmt7 = try db.prepare(unsafeQuery1, [""]) // $ Alert
let stmt7 = try db.prepare(unsafeQuery1, [""]) // BAD
try stmt7.run()
let stmt8 = try db.prepare(unsafeQuery1, ["username": ""]) // $ Alert
let stmt8 = try db.prepare(unsafeQuery1, ["username": ""]) // BAD
try stmt8.run()
try db.run(unsafeQuery1, "") // $ Alert
try db.run(unsafeQuery1, "") // BAD
try db.run(unsafeQuery1, [""]) // $ Alert
try db.run(unsafeQuery1, [""]) // BAD
try db.run(unsafeQuery1, ["username": ""]) // $ Alert
try db.run(unsafeQuery1, ["username": ""]) // BAD
try db.scalar(unsafeQuery1, "") // $ Alert
try db.scalar(unsafeQuery1, "") // BAD
try db.scalar(unsafeQuery1, [""]) // $ Alert
try db.scalar(unsafeQuery1, [""]) // BAD
try db.scalar(unsafeQuery1, ["username": ""]) // $ Alert
try db.scalar(unsafeQuery1, ["username": ""]) // BAD
let stmt9 = try db.prepare(varQuery) // GOOD
try stmt9.bind(remoteString) // GOOD
@@ -129,5 +129,5 @@ func test_sqlite_swift_api(db: Connection) throws {
try stmt9.scalar([remoteString]) // GOOD
try stmt9.scalar(["username": remoteString]) // GOOD
try Statement(db, remoteString).run() // $ Alert
try Statement(db, remoteString).run() // BAD
}

View File

@@ -1,2 +1 @@
query: queries/Security/CWE-089/SqlInjection.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
queries/Security/CWE-089/SqlInjection.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/")!) // $ Source
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
_ = MyDatabase() // GOOD
_ = MyDatabase(sql: "some_fixed_sql") // GOOD
_ = MyDatabase(sql: remoteString) // $ Alert
_ = MyDatabase(sql: remoteString) // BAD
db.execute1(remoteString) // $ Alert
db.execute2(remoteString) // $ Alert
db.execute3(NSString(string: remoteString)) // $ Alert
db.execute4(remoteString as! Sql) // $ Alert
db.execute1(remoteString) // BAD
db.execute2(remoteString) // BAD
db.execute3(NSString(string: remoteString)) // BAD
db.execute4(remoteString as! Sql) // BAD
db.query(sql: remoteString) // $ Alert
db.query(sql: remoteString) // BAD
db.query(sqlLiteral: remoteString) // BAD [NOT DETECTED]
db.query(sqlStatement: remoteString) // BAD [NOT DETECTED]
db.query(sqliteStatement: remoteString) // BAD [NOT DETECTED]

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/")!) // $ Source
let remoteString = try! String(contentsOf: URL(string: "http://example.com/")!)
let remoteNumber = Int(remoteString) ?? 0
let unsafeQuery1 = remoteString
@@ -130,9 +130,9 @@ func test_sqlite3_c_api(db: OpaquePointer?, buffer: UnsafeMutablePointer<UInt8>)
// --- exec ---
let result1 = sqlite3_exec(db, unsafeQuery1, nil, nil, nil) // $ Alert
let result2 = sqlite3_exec(db, unsafeQuery2, nil, nil, nil) // $ Alert
let result3 = sqlite3_exec(db, unsafeQuery3, nil, nil, nil) // $ Alert
let result1 = sqlite3_exec(db, unsafeQuery1, nil, nil, nil) // BAD
let result2 = sqlite3_exec(db, unsafeQuery2, nil, nil, nil) // BAD
let result3 = sqlite3_exec(db, unsafeQuery3, nil, nil, nil) // BAD
let result4 = sqlite3_exec(db, safeQuery1, nil, nil, nil) // GOOD
let result5 = sqlite3_exec(db, safeQuery2, nil, nil, nil) // GOOD
@@ -142,7 +142,7 @@ func test_sqlite3_c_api(db: OpaquePointer?, buffer: UnsafeMutablePointer<UInt8>)
var stmt1: OpaquePointer?
if (sqlite3_prepare(db, unsafeQuery3, -1, &stmt1, nil) == SQLITE_OK) { // $ Alert
if (sqlite3_prepare(db, unsafeQuery3, -1, &stmt1, nil) == SQLITE_OK) { // BAD
let result = sqlite3_step(stmt1)
// ...
}
@@ -172,7 +172,7 @@ func test_sqlite3_c_api(db: OpaquePointer?, buffer: UnsafeMutablePointer<UInt8>)
var stmt4: OpaquePointer?
if (sqlite3_prepare_v2(db, unsafeQuery3, -1, &stmt4, nil) == SQLITE_OK) { // $ Alert
if (sqlite3_prepare_v2(db, unsafeQuery3, -1, &stmt4, nil) == SQLITE_OK) { // BAD
let result = sqlite3_step(stmt4)
// ...
}
@@ -180,7 +180,7 @@ func test_sqlite3_c_api(db: OpaquePointer?, buffer: UnsafeMutablePointer<UInt8>)
var stmt5: OpaquePointer?
if (sqlite3_prepare_v3(db, unsafeQuery3, -1, 0, &stmt5, nil) == SQLITE_OK) { // $ Alert
if (sqlite3_prepare_v3(db, unsafeQuery3, -1, 0, &stmt5, nil) == SQLITE_OK) { // BAD
let result = sqlite3_step(stmt5)
// ...
}
@@ -191,7 +191,7 @@ func test_sqlite3_c_api(db: OpaquePointer?, buffer: UnsafeMutablePointer<UInt8>)
var stmt6: OpaquePointer?
if (sqlite3_prepare16(db, buffer, Int32(data.count), &stmt6, nil) == SQLITE_OK) { // $ Alert
if (sqlite3_prepare16(db, buffer, Int32(data.count), &stmt6, nil) == SQLITE_OK) { // BAD
let result = sqlite3_step(stmt6)
// ...
}
@@ -199,7 +199,7 @@ func test_sqlite3_c_api(db: OpaquePointer?, buffer: UnsafeMutablePointer<UInt8>)
var stmt7: OpaquePointer?
if (sqlite3_prepare16_v2(db, buffer, Int32(data.count), &stmt7, nil) == SQLITE_OK) { // $ Alert
if (sqlite3_prepare16_v2(db, buffer, Int32(data.count), &stmt7, nil) == SQLITE_OK) { // BAD
let result = sqlite3_step(stmt7)
// ...
}
@@ -207,7 +207,7 @@ func test_sqlite3_c_api(db: OpaquePointer?, buffer: UnsafeMutablePointer<UInt8>)
var stmt8: OpaquePointer?
if (sqlite3_prepare16_v3(db, buffer, Int32(data.count), 0, &stmt8, nil) == SQLITE_OK) { // $ Alert
if (sqlite3_prepare16_v3(db, buffer, Int32(data.count), 0, &stmt8, nil) == SQLITE_OK) { // BAD
let result = sqlite3_step(stmt8)
// ...
}

View File

@@ -1,2 +1 @@
query: queries/Security/CWE-116/BadTagFilter.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
queries/Security/CWE-116/BadTagFilter.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) // $ Alert
let re1 = try Regex(#"<script.*?>.*?<\/script>"#).ignoresCase(true)
_ = try re1.firstMatch(in: tainted)
// BAD - doesn't match `</script >`
let re2a = try Regex(#"(?is)<script.*?>.*?<\/script>"#) // $ Alert
let re2a = try Regex(#"(?is)<script.*?>.*?<\/script>"#)
_ = try re2a.firstMatch(in: tainted)
// BAD - doesn't match `</script >`
let re2b = try Regex(#"<script.*?>.*?<\/script>"#).ignoresCase(true).dotMatchesNewlines(true) // $ Alert
let re2b = try Regex(#"<script.*?>.*?<\/script>"#).ignoresCase(true).dotMatchesNewlines(true)
_ = try re2b.firstMatch(in: tainted)
// BAD - doesn't match `</script >`
let options2c: NSRegularExpression.Options = [.caseInsensitive, .dotMatchesLineSeparators]
let ns2c = try NSRegularExpression(pattern: #"<script.*?>.*?<\/script>"#, options: options2c) // $ Alert
let ns2c = try NSRegularExpression(pattern: #"<script.*?>.*?<\/script>"#, options: options2c)
_ = ns2c.firstMatch(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
// GOOD
@@ -110,71 +110,71 @@ func myRegexpVariantsTests(myUrl: URL) throws {
_ = try re5.firstMatch(in: tainted)
// BAD, does not match newlines
let re6 = try Regex(#"<!--.*--!?>"#).ignoresCase(true) // $ Alert
let re6 = try Regex(#"<!--.*--!?>"#).ignoresCase(true)
_ = try re6.firstMatch(in: tainted)
// BAD - doesn't match newlines inside the script tag
let re7 = try Regex(#"<script.*?>(.|\s)*?<\/script[^>]*>"#).ignoresCase(true) // $ Alert
let re7 = try Regex(#"<script.*?>(.|\s)*?<\/script[^>]*>"#).ignoresCase(true)
_ = try re7.firstMatch(in: tainted)
// BAD - doesn't match newlines inside the content
let re8 = try Regex(#"<script[^>]*?>.*?<\/script[^>]*>"#).ignoresCase(true) // $ Alert
let re8 = try Regex(#"<script[^>]*?>.*?<\/script[^>]*>"#).ignoresCase(true)
_ = try re8.firstMatch(in: tainted)
// BAD - does not match single quotes for attribute values
let re9 = try Regex(#"<script(\s|\w|=|")*?>.*?<\/script[^>]*>"#).ignoresCase(true).dotMatchesNewlines(true) // $ Alert
let re9 = try Regex(#"<script(\s|\w|=|")*?>.*?<\/script[^>]*>"#).ignoresCase(true).dotMatchesNewlines(true)
_ = try re9.firstMatch(in: tainted)
// BAD - does not match double quotes for attribute values
let re10a = try Regex(#"(?is)<script(\s|\w|=|')*?>.*?<\/script[^>]*>"#) // $ Alert
let re10a = try Regex(#"(?is)<script(\s|\w|=|')*?>.*?<\/script[^>]*>"#)
_ = try re10a.firstMatch(in: tainted)
// BAD - does not match double quotes for attribute values
let re10b = try Regex(#"<script(\s|\w|=|')*?>.*?<\/script[^>]*>"#).ignoresCase(true).dotMatchesNewlines(true) // $ Alert
let re10b = try Regex(#"<script(\s|\w|=|')*?>.*?<\/script[^>]*>"#).ignoresCase(true).dotMatchesNewlines(true)
_ = try re10b.firstMatch(in: tainted)
// BAD - does not match double quotes for attribute values
let options10: NSRegularExpression.Options = [.caseInsensitive, .dotMatchesLineSeparators]
let ns10 = try NSRegularExpression(pattern: #"<script(\s|\w|=|')*?>.*?<\/script[^>]*>"#, options: options10) // $ Alert
let ns10 = try NSRegularExpression(pattern: #"<script(\s|\w|=|')*?>.*?<\/script[^>]*>"#, options: options10)
_ = ns10.firstMatch(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
// BAD - does not match tabs between attributes
let re11a = try Regex(#"(?is)<script( |\n|\w|=|'|")*?>.*?<\/script[^>]*>"#) // $ Alert
let re11a = try Regex(#"(?is)<script( |\n|\w|=|'|")*?>.*?<\/script[^>]*>"#)
_ = try re11a.firstMatch(in: tainted)
// BAD - does not match tabs between attributes
let re11b = try Regex(#"<script( |\n|\w|=|'|")*?>.*?<\/script[^>]*>"#).ignoresCase(true).dotMatchesNewlines(true) // $ Alert
let re11b = try Regex(#"<script( |\n|\w|=|'|")*?>.*?<\/script[^>]*>"#).ignoresCase(true).dotMatchesNewlines(true)
_ = try re11b.firstMatch(in: tainted)
// BAD - does not match tabs between attributes
let options11: NSRegularExpression.Options = [.caseInsensitive, .dotMatchesLineSeparators]
let ns11 = try NSRegularExpression(pattern: #"<script( |\n|\w|=|'|")*?>.*?<\/script[^>]*>"#, options: options11) // $ Alert
let ns11 = try NSRegularExpression(pattern: #"<script( |\n|\w|=|'|")*?>.*?<\/script[^>]*>"#, options: options11)
_ = ns11.firstMatch(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
// BAD - does not match uppercase SCRIPT tags
let re12a = try Regex(#"(?s)<script.*?>.*?<\/script[^>]*>"#) // $ Alert
let re12a = try Regex(#"(?s)<script.*?>.*?<\/script[^>]*>"#)
_ = try re12a.firstMatch(in: tainted)
// BAD - does not match uppercase SCRIPT tags
let re12b = try Regex(#"<script.*?>.*?<\/script[^>]*>"#).dotMatchesNewlines(true) // $ Alert
let re12b = try Regex(#"<script.*?>.*?<\/script[^>]*>"#).dotMatchesNewlines(true)
_ = try re12b.firstMatch(in: tainted)
// BAD - does not match uppercase SCRIPT tags
let ns12 = try NSRegularExpression(pattern: #"<script.*?>.*?<\/script[^>]*>"#, options: .dotMatchesLineSeparators) // $ Alert
let ns12 = try NSRegularExpression(pattern: #"<script.*?>.*?<\/script[^>]*>"#, options: .dotMatchesLineSeparators)
_ = ns12.firstMatch(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
// BAD - does not match mixed case script tags
let re13a = try Regex(#"(?s)<(script|SCRIPT).*?>.*?<\/(script|SCRIPT)[^>]*>"#) // $ Alert
let re13a = try Regex(#"(?s)<(script|SCRIPT).*?>.*?<\/(script|SCRIPT)[^>]*>"#)
_ = try re13a.firstMatch(in: tainted)
// BAD - does not match mixed case script tags
let re13b = try Regex(#"<(script|SCRIPT).*?>.*?<\/(script|SCRIPT)[^>]*>"#).dotMatchesNewlines(true) // $ Alert
let re13b = try Regex(#"<(script|SCRIPT).*?>.*?<\/(script|SCRIPT)[^>]*>"#).dotMatchesNewlines(true)
_ = try re13b.firstMatch(in: tainted)
// BAD - does not match mixed case script tags
let ns13 = try NSRegularExpression(pattern: #"<(script|SCRIPT).*?>.*?<\/(script|SCRIPT)[^>]*>"#, options: .dotMatchesLineSeparators) // $ Alert
let ns13 = try NSRegularExpression(pattern: #"<(script|SCRIPT).*?>.*?<\/(script|SCRIPT)[^>]*>"#, options: .dotMatchesLineSeparators)
_ = ns13.firstMatch(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
// BAD - doesn't match newlines in the end tag
let re14a = try Regex(#"(?i)<script[^>]*?>[\s\S]*?<\/script.*>"#) // $ Alert
let re14a = try Regex(#"(?i)<script[^>]*?>[\s\S]*?<\/script.*>"#)
_ = try re14a.firstMatch(in: tainted)
// BAD - doesn't match newlines in the end tag
let re14b = try Regex(#"<script[^>]*?>[\s\S]*?<\/script.*>"#).ignoresCase(true) // $ Alert
let re14b = try Regex(#"<script[^>]*?>[\s\S]*?<\/script.*>"#).ignoresCase(true)
_ = try re14b.firstMatch(in: tainted)
// BAD - doesn't match newlines in the end tag
let ns14 = try NSRegularExpression(pattern: #"<script[^>]*?>[\s\S]*?<\/script.*>"#, options: .caseInsensitive) // $ Alert
let ns14 = try NSRegularExpression(pattern: #"<script[^>]*?>[\s\S]*?<\/script.*>"#, options: .caseInsensitive)
_ = ns14.firstMatch(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
// GOOD
@@ -188,33 +188,33 @@ func myRegexpVariantsTests(myUrl: URL) throws {
_ = ns15.firstMatch(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
// BAD - doesn't match comments with the right capture groups
let re16 = try Regex(#"<(?:!--([\S|\s]*?)-->)|([^\/\s>]+)[\S\s]*?>"#) // $ Alert
let re16 = try Regex(#"<(?:!--([\S|\s]*?)-->)|([^\/\s>]+)[\S\s]*?>"#)
_ = try re16.firstMatch(in: tainted)
// BAD - doesn't match comments with the right capture groups
let ns16 = try NSRegularExpression(pattern: #"<(?:!--([\S|\s]*?)-->)|([^\/\s>]+)[\S\s]*?>"#) // $ Alert
let ns16 = try NSRegularExpression(pattern: #"<(?:!--([\S|\s]*?)-->)|([^\/\s>]+)[\S\s]*?>"#)
_ = ns16.firstMatch(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
// BAD - capture groups
let re17 = try Regex(#"<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\/\s>]+)((?:\s+[\w\-:.]+(?:\s*=\s*?(?:(?:"[^"]*")|(?:'[^']*')|[^\s"'\/>]+))?)*)[\S\s]*?(\/?)>))"#) // $ Alert
let re17 = try Regex(#"<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\/\s>]+)((?:\s+[\w\-:.]+(?:\s*=\s*?(?:(?:"[^"]*")|(?:'[^']*')|[^\s"'\/>]+))?)*)[\S\s]*?(\/?)>))"#)
_ = try re17.firstMatch(in: tainted)
// BAD - capture groups
let ns17 = try NSRegularExpression(pattern: #"<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\/\s>]+)((?:\s+[\w\-:.]+(?:\s*=\s*?(?:(?:"[^"]*")|(?:'[^']*')|[^\s"'\/>]+))?)*)[\S\s]*?(\/?)>))"#, options: .caseInsensitive) // $ Alert
let ns17 = try NSRegularExpression(pattern: #"<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\/\s>]+)((?:\s+[\w\-:.]+(?:\s*=\s*?(?:(?:"[^"]*")|(?:'[^']*')|[^\s"'\/>]+))?)*)[\S\s]*?(\/?)>))"#, options: .caseInsensitive)
_ = ns17.firstMatch(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
// BAD - too strict matching on the end tag
let ns2_1 = try NSRegularExpression(pattern: #"<script\b[^>]*>([\s\S]*?)<\/script>"#, options: .caseInsensitive) // $ Alert
let ns2_1 = try NSRegularExpression(pattern: #"<script\b[^>]*>([\s\S]*?)<\/script>"#, options: .caseInsensitive)
_ = ns2_1.matches(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
// BAD - capture groups
let ns2_2 = try NSRegularExpression(pattern: #"(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|<!(--.*?--\s*)+>)"#, options: .caseInsensitive) // $ Alert
let ns2_2 = try NSRegularExpression(pattern: #"(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|<!(--.*?--\s*)+>)"#, options: .caseInsensitive)
_ = ns2_2.matches(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
// BAD - capture groups
let ns2_3 = try NSRegularExpression(pattern: #"<(?:(?:!--([\w\W]*?)-->)|(?:!\[CDATA\[([\w\W]*?)\]\]>)|(?:!DOCTYPE([\w\W]*?)>)|(?:\?([^\s\/<>]+) ?([\w\W]*?)[?/]>)|(?:\/([A-Za-z][A-Za-z0-9\-_\:\.]*)>)|(?:([A-Za-z][A-Za-z0-9\-_\:\.]*)((?:\s+[^"'>]+(?:(?:"[^"]*")|(?:'[^']*')|[^>]*))*|\/|\s+)>))"#) // $ Alert
let ns2_3 = try NSRegularExpression(pattern: #"<(?:(?:!--([\w\W]*?)-->)|(?:!\[CDATA\[([\w\W]*?)\]\]>)|(?:!DOCTYPE([\w\W]*?)>)|(?:\?([^\s\/<>]+) ?([\w\W]*?)[?/]>)|(?:\/([A-Za-z][A-Za-z0-9\-_\:\.]*)>)|(?:([A-Za-z][A-Za-z0-9\-_\:\.]*)((?:\s+[^"'>]+(?:(?:"[^"]*")|(?:'[^']*')|[^>]*))*|\/|\s+)>))"#)
_ = ns2_3.matches(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
// BAD - capture groups
let ns2_4 = try NSRegularExpression(pattern: #"<!--([\w\W]*?)-->|<([^>]*?)>"#) // $ Alert
let ns2_4 = try NSRegularExpression(pattern: #"<!--([\w\W]*?)-->|<([^>]*?)>"#)
_ = ns2_4.matches(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
// GOOD - it's used with the ignorecase flag
@@ -222,7 +222,7 @@ func myRegexpVariantsTests(myUrl: URL) throws {
_ = ns2_5.matches(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
// BAD - doesn't match --!>
let ns2_6 = try NSRegularExpression(pattern: #"-->"#) // $ Alert
let ns2_6 = try NSRegularExpression(pattern: #"-->"#)
_ = ns2_6.matches(in: tainted, range: NSMakeRange(0, tainted.utf16.count))
// GOOD

View File

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

View File

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

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

View File

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

View File

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

View File

@@ -1,2 +1 @@
query: queries/Security/CWE-134/UncontrolledFormatString.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
queries/Security/CWE-134/UncontrolledFormatString.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) // $ Alert
NSLogv(format, arglist) // BAD
}
}
@@ -88,34 +88,34 @@ class MyString {
}
func tests() throws {
let tainted = try! String(contentsOf: URL(string: "http://example.com")!) // $ Source
let tainted = try! String(contentsOf: URL(string: "http://example.com")!)
_ = String("abc") // GOOD: not a format string
_ = String(tainted) // GOOD: not a format string
_ = String(format: "abc") // GOOD: not tainted
_ = String(format: tainted) // $ Alert
_ = String(format: tainted) // BAD
_ = String(format: "%s", "abc") // GOOD: not tainted
_ = String(format: "%s", tainted) // GOOD: format string itself is not tainted
_ = String(format: tainted, "abc") // $ Alert
_ = String(format: tainted, tainted) // $ Alert
_ = String(format: tainted, "abc") // BAD
_ = String(format: tainted, tainted) // BAD
_ = String(format: tainted, arguments: []) // $ Alert
_ = String(format: tainted, locale: nil) // $ Alert
_ = String(format: tainted, locale: nil, arguments: []) // $ Alert
_ = String.localizedStringWithFormat(tainted) // $ Alert
_ = String(format: tainted, arguments: []) // BAD
_ = String(format: tainted, locale: nil) // BAD
_ = String(format: tainted, locale: nil, arguments: []) // BAD
_ = String.localizedStringWithFormat(tainted) // BAD
_ = NSString(format: NSString(string: tainted), "abc") // $ Alert
NSString.localizedStringWithFormat(NSString(string: tainted)) // $ Alert
_ = NSString(format: NSString(string: tainted), "abc") // BAD
NSString.localizedStringWithFormat(NSString(string: tainted)) // BAD
_ = NSMutableString(format: NSString(string: tainted), "abc") // $ Alert
NSMutableString.localizedStringWithFormat(NSString(string: tainted)) // $ Alert
_ = NSMutableString(format: NSString(string: tainted), "abc") // BAD
NSMutableString.localizedStringWithFormat(NSString(string: tainted)) // BAD
NSLog("abc") // GOOD: not tainted
NSLog(tainted) // $ Alert
MyLog(tainted) // $ Alert
NSLog(tainted) // BAD
MyLog(tainted) // BAD
NSException.raise(NSExceptionName("exception"), format: tainted, arguments: getVaList([])) // $ Alert
NSException.raise(NSExceptionName("exception"), format: tainted, arguments: getVaList([])) // BAD
let taintedVal = Int(tainted)!
let taintedSan = "\(taintedVal)"
@@ -127,32 +127,32 @@ func tests() throws {
_ = String("abc").appendingFormat("%s", "abc") // GOOD: not tainted
_ = String("abc").appendingFormat("%s", tainted) // GOOD: format not tainted
_ = String("abc").appendingFormat(tainted, "abc") // $ Alert
_ = String("abc").appendingFormat(tainted, "abc") // BAD
_ = String(tainted).appendingFormat("%s", "abc") // GOOD: format not tainted
let s = NSMutableString(string: "foo")
s.appendFormat(NSString(string: "%s"), "abc") // GOOD: not tainted
s.appendFormat(NSString(string: tainted), "abc") // $ Alert
s.appendFormat(NSString(string: tainted), "abc") // BAD
_ = NSPredicate(format: tainted) // GOOD: this should be flagged by `swift/predicate-injection`, not `swift/uncontrolled-format-string`
tainted.withCString({
cstr in
_ = dprintf(0, cstr, "abc") // $ Alert
_ = dprintf(0, cstr, "abc") // BAD
_ = dprintf(0, "%s", cstr) // GOOD: format not tainted
_ = vprintf(cstr, getVaList(["abc"])) // $ Alert
_ = vprintf(cstr, getVaList(["abc"])) // BAD
_ = vprintf("%s", getVaList([cstr])) // GOOD: format not tainted
_ = vfprintf(nil, cstr, getVaList(["abc"])) // $ Alert
_ = vfprintf(nil, cstr, getVaList(["abc"])) // BAD
_ = vfprintf(nil, "%s", getVaList([cstr])) // GOOD: format not tainted
_ = vasprintf_l(nil, nil, cstr, getVaList(["abc"])) // $ Alert
_ = vasprintf_l(nil, nil, cstr, getVaList(["abc"])) // BAD
_ = vasprintf_l(nil, nil, "%s", getVaList([cstr])) // GOOD: format not tainted
})
myFormatMessage(string: tainted, "abc") // BAD [NOT DETECTED]
myFormatMessage(string: "%s", tainted) // GOOD: format not tainted
_ = MyString(format: tainted, "abc") // $ Alert
_ = MyString(format: tainted, "abc") // BAD
_ = MyString(format: "%s", tainted) // GOOD: format not tainted
_ = MyString(formatString: tainted, "abc") // $ Alert
_ = MyString(formatString: tainted, "abc") // BAD
_ = MyString(formatString: "%s", tainted) // GOOD: format not tainted
}

View File

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

View File

@@ -66,7 +66,7 @@ func test(cond: Bool) {
let myData = Data(0)
let myRandomPassword = getARandomPassword()
let myConstPassword = "abc123" // $ Source
let myConstPassword = "abc123"
let myMaybePassword = cond ? myRandomPassword : myConstPassword
// reasonable usage
@@ -74,11 +74,11 @@ func test(cond: Bool) {
let a = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myRandomPassword) // GOOD
let _ = try? myDecryptor.decryptData(a, withPassword: myRandomPassword) // GOOD
let b = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myConstPassword) // $ Alert
let _ = try? myDecryptor.decryptData(b, withPassword: myConstPassword) // $ Alert
let b = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myConstPassword) // BAD
let _ = try? myDecryptor.decryptData(b, withPassword: myConstPassword) // BAD
let c = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myMaybePassword) // $ Alert
let _ = try? myDecryptor.decryptData(c, withPassword: myMaybePassword) // $ Alert
let c = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myMaybePassword) // BAD
let _ = try? myDecryptor.decryptData(c, withPassword: myMaybePassword) // BAD
// all methods
@@ -88,22 +88,22 @@ func test(cond: Bool) {
let mySalt = Data(0)
let mySalt2 = Data(0)
let _ = myEncryptor.key(forPassword: myConstPassword, salt: mySalt, settings: myKeyDerivationSettings) // $ Alert
let _ = myEncryptor.keyForPassword(myConstPassword, salt: mySalt, settings: myKeyDerivationSettings) // $ Alert
let _ = myDecryptor.key(forPassword: myConstPassword, salt: mySalt, settings: myKeyDerivationSettings) // $ Alert
let _ = myDecryptor.keyForPassword(myConstPassword, salt: mySalt, settings: myKeyDerivationSettings) // $ Alert
let _ = myEncryptor.key(forPassword: myConstPassword, salt: mySalt, settings: myKeyDerivationSettings) // BAD
let _ = myEncryptor.keyForPassword(myConstPassword, salt: mySalt, settings: myKeyDerivationSettings) // BAD
let _ = myDecryptor.key(forPassword: myConstPassword, salt: mySalt, settings: myKeyDerivationSettings) // BAD
let _ = myDecryptor.keyForPassword(myConstPassword, salt: mySalt, settings: myKeyDerivationSettings) // BAD
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myConstPassword, handler: myHandler) // $ Alert
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myConstPassword, iv: myIV, encryptionSalt: mySalt, hmacSalt: mySalt2, handler: myHandler) // $ Alert
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myConstPassword, IV: myIV, encryptionSalt: mySalt, HMACSalt: mySalt2, handler: myHandler) // $ Alert
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myConstPassword, handler: myHandler) // BAD
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myConstPassword, iv: myIV, encryptionSalt: mySalt, hmacSalt: mySalt2, handler: myHandler) // BAD
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myConstPassword, IV: myIV, encryptionSalt: mySalt, HMACSalt: mySalt2, handler: myHandler) // BAD
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myConstPassword) // $ Alert
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, password: myConstPassword) // $ Alert
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myConstPassword, iv: myIV, encryptionSalt: mySalt, hmacSalt: mySalt2) // $ Alert
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, password: myConstPassword, IV: myIV, encryptionSalt: mySalt, HMACSalt: mySalt2) // $ Alert
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myConstPassword) // BAD
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, password: myConstPassword) // BAD
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myConstPassword, iv: myIV, encryptionSalt: mySalt, hmacSalt: mySalt2) // BAD
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, password: myConstPassword, IV: myIV, encryptionSalt: mySalt, HMACSalt: mySalt2) // BAD
let _ = RNDecryptor(password: myConstPassword, handler: myHandler) // $ Alert
let _ = RNDecryptor(password: myConstPassword, handler: myHandler) // BAD
let _ = try? myDecryptor.decryptData(myData, withPassword: myConstPassword) // $ Alert
let _ = try? myDecryptor.decryptData(myData, withSettings: kRNCryptorAES256Settings, password: myConstPassword) // $ Alert
let _ = try? myDecryptor.decryptData(myData, withPassword: myConstPassword) // BAD
let _ = try? myDecryptor.decryptData(myData, withSettings: kRNCryptorAES256Settings, password: myConstPassword) // BAD
}

View File

@@ -26,7 +26,7 @@ final class Scrypt {
// Helper functions
func getConstantString() -> String {
"this string is constant" // $ Source
"this string is constant"
}
func getConstantArray() -> Array<UInt8> {
@@ -40,7 +40,7 @@ func getRandomArray() -> Array<UInt8> {
// --- tests ---
func test() {
let constantPassword: Array<UInt8> = [0x2a, 0x3a, 0x80, 0x05, 0xaf, 0x46, 0x58, 0x2d, 0x66, 0x52, 0x10, 0xae, 0x86, 0xd3, 0x8e, 0x8f] // $ Source
let constantPassword: Array<UInt8> = [0x2a, 0x3a, 0x80, 0x05, 0xaf, 0x46, 0x58, 0x2d, 0x66, 0x52, 0x10, 0xae, 0x86, 0xd3, 0x8e, 0x8f]
let constantStringPassword = getConstantArray()
let randomPassword = getRandomArray()
let randomArray = getRandomArray()
@@ -48,23 +48,23 @@ func test() {
let iterations = 120120
// HKDF test cases
let hkdfb1 = HKDF(password: constantPassword, salt: randomArray, info: randomArray, keyLength: 0, variant: variant) // $ Alert
let hkdfb2 = HKDF(password: constantStringPassword, salt: randomArray, info: randomArray, keyLength: 0, variant: variant) // $ Alert
let hkdfb1 = HKDF(password: constantPassword, salt: randomArray, info: randomArray, keyLength: 0, variant: variant) // BAD
let hkdfb2 = HKDF(password: constantStringPassword, salt: randomArray, info: randomArray, keyLength: 0, variant: variant) // BAD
let hkdfg1 = HKDF(password: randomPassword, salt: randomArray, info: randomArray, keyLength: 0, variant: variant) // GOOD
// PBKDF1 test cases
let pbkdf1b1 = PKCS5.PBKDF1(password: constantPassword, salt: randomArray, iterations: iterations, keyLength: 0) // $ Alert
let pbkdf1b2 = PKCS5.PBKDF1(password: constantStringPassword, salt: randomArray, iterations: iterations, keyLength: 0) // $ Alert
let pbkdf1b1 = PKCS5.PBKDF1(password: constantPassword, salt: randomArray, iterations: iterations, keyLength: 0) // BAD
let pbkdf1b2 = PKCS5.PBKDF1(password: constantStringPassword, salt: randomArray, iterations: iterations, keyLength: 0) // BAD
let pbkdf1g1 = PKCS5.PBKDF1(password: randomPassword, salt: randomArray, iterations: iterations, keyLength: 0) // GOOD
// PBKDF2 test cases
let pbkdf2b1 = PKCS5.PBKDF2(password: constantPassword, salt: randomArray, iterations: iterations, keyLength: 0) // $ Alert
let pbkdf2b2 = PKCS5.PBKDF2(password: constantStringPassword, salt: randomArray, iterations: iterations, keyLength: 0) // $ Alert
let pbkdf2b1 = PKCS5.PBKDF2(password: constantPassword, salt: randomArray, iterations: iterations, keyLength: 0) // BAD
let pbkdf2b2 = PKCS5.PBKDF2(password: constantStringPassword, salt: randomArray, iterations: iterations, keyLength: 0) // BAD
let pbkdf2g1 = PKCS5.PBKDF2(password: randomPassword, salt: randomArray, iterations: iterations, keyLength: 0) // GOOD
// Scrypt test cases
let scryptb1 = Scrypt(password: constantPassword, salt: randomArray, dkLen: 64, N: 16384, r: 8, p: 1) // $ Alert
let scryptb2 = Scrypt(password: constantStringPassword, salt: randomArray, dkLen: 64, N: 16384, r: 8, p: 1) // $ Alert
let scryptb1 = Scrypt(password: constantPassword, salt: randomArray, dkLen: 64, N: 16384, r: 8, p: 1) // BAD
let scryptb2 = Scrypt(password: constantStringPassword, salt: randomArray, dkLen: 64, N: 16384, r: 8, p: 1) // BAD
let scryptg1 = Scrypt(password: randomPassword, salt: randomArray, dkLen: 64, N: 16384, r: 8, p: 1) // GOOD
}

View File

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

View File

@@ -1,2 +1 @@
query: queries/Security/CWE-311/CleartextTransmission.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
queries/Security/CWE-311/CleartextTransmission.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));" // $ Source
let updateQuery = "UPDATE CONTACTS SET NUMBER=\(mobilePhoneNumber) WHERE ID=\(id);" // $ Source
let insertQuery = "INSERT INTO CONTACTS(ID, NUMBER) VALUES(\(id), \(mobilePhoneNumber));"
let updateQuery = "UPDATE CONTACTS SET NUMBER=\(mobilePhoneNumber) WHERE ID=\(id);"
let deleteQuery = "DELETE FROM CONTACTS WHERE ID=\(id);"
try db.execute(insertQuery) // $ Alert // BAD (sensitive data)
try db.execute(updateQuery) // $ Alert // BAD (sensitive data)
try db.execute(insertQuery) // BAD (sensitive data)
try db.execute(updateQuery) // BAD (sensitive data)
try db.execute(deleteQuery) // GOOD
_ = try db.prepare(insertQuery).run() // $ Alert // BAD (sensitive data)
_ = try db.prepare(updateQuery).run() // $ Alert // BAD (sensitive data)
_ = try db.prepare(insertQuery).run() // BAD (sensitive data)
_ = try db.prepare(updateQuery).run() // BAD (sensitive data)
_ = try db.prepare(deleteQuery).run() // GOOD
_ = try db.run(insertQuery) // $ Alert // BAD (sensitive data)
_ = try db.run(updateQuery) // $ Alert // BAD (sensitive data)
_ = try db.run(insertQuery) // BAD (sensitive data)
_ = try db.run(updateQuery) // BAD (sensitive data)
_ = try db.run(deleteQuery) // GOOD
_ = try db.scalar(insertQuery) // $ Alert // BAD (sensitive data)
_ = try db.scalar(updateQuery) // $ Alert // BAD (sensitive data)
_ = try db.scalar(insertQuery) // BAD (sensitive data)
_ = try db.scalar(updateQuery) // BAD (sensitive data)
_ = try db.scalar(deleteQuery) // GOOD
_ = try Statement(db, insertQuery).run() // $ Alert // BAD (sensitive data)
_ = try Statement(db, updateQuery).run() // $ Alert // BAD (sensitive data)
_ = try Statement(db, insertQuery).run() // BAD (sensitive data)
_ = try Statement(db, updateQuery).run() // BAD (sensitive data)
_ = try Statement(db, deleteQuery).run() // GOOD
// --- sensitive data in bindings ---
let varQuery1 = "UPDATE CONTACTS SET NUMBER=?;"
_ = try db.prepare(varQuery1, mobilePhoneNumber).run() // $ Alert // BAD (sensitive data)
_ = try db.run(varQuery1, mobilePhoneNumber) // $ Alert // BAD (sensitive data)
_ = try db.scalar(varQuery1, mobilePhoneNumber) // $ Alert // BAD (sensitive data)
_ = try db.prepare(varQuery1, mobilePhoneNumber).run() // BAD (sensitive data)
_ = try db.run(varQuery1, mobilePhoneNumber) // BAD (sensitive data)
_ = try db.scalar(varQuery1, mobilePhoneNumber) // BAD (sensitive data)
let stmt1 = try db.prepare(varQuery1) // GOOD
_ = try stmt1.bind(mobilePhoneNumber).run() // $ Alert // BAD (sensitive data)
_ = try stmt1.run(mobilePhoneNumber) // $ Alert // BAD (sensitive data)
_ = try stmt1.scalar(mobilePhoneNumber) // $ Alert // BAD (sensitive data)
_ = try stmt1.bind(mobilePhoneNumber).run() // BAD (sensitive data)
_ = try stmt1.run(mobilePhoneNumber) // BAD (sensitive data)
_ = try stmt1.scalar(mobilePhoneNumber) // BAD (sensitive data)
let varQuery2 = "UPDATE CONTACTS SET NUMBER=? WHERE ID=?;"
_ = try db.prepare(varQuery2, [mobilePhoneNumber, id]).run() // $ Alert // BAD (sensitive data)
_ = try db.run(varQuery2, [mobilePhoneNumber, id]) // $ Alert // BAD (sensitive data)
_ = try db.scalar(varQuery2, [mobilePhoneNumber, id]) // $ Alert // BAD (sensitive data)
_ = try db.prepare(varQuery2, [mobilePhoneNumber, id]).run() // BAD (sensitive data)
_ = try db.run(varQuery2, [mobilePhoneNumber, id]) // BAD (sensitive data)
_ = try db.scalar(varQuery2, [mobilePhoneNumber, id]) // BAD (sensitive data)
let stmt2 = try db.prepare(varQuery2) // GOOD
_ = try stmt2.bind([mobilePhoneNumber, id]).run() // $ Alert // BAD (sensitive data)
_ = try stmt2.run([mobilePhoneNumber, id]) // $ Alert // BAD (sensitive data)
_ = try stmt2.scalar([mobilePhoneNumber, id]) // $ Alert // BAD (sensitive data)
_ = try stmt2.bind([mobilePhoneNumber, id]).run() // BAD (sensitive data)
_ = try stmt2.run([mobilePhoneNumber, id]) // BAD (sensitive data)
_ = try stmt2.scalar([mobilePhoneNumber, id]) // BAD (sensitive data)
let varQuery3 = "UPDATE CONTACTS SET NUMBER=$number WHERE ID=$id;"
_ = try db.prepare(varQuery3, ["id": id, "number": mobilePhoneNumber]).run() // $ Alert // BAD (sensitive data)
_ = try db.run(varQuery3, ["id": id, "number": mobilePhoneNumber]) // $ Alert // BAD (sensitive data)
_ = try db.scalar(varQuery3, ["id": id, "number": mobilePhoneNumber]) // $ Alert // BAD (sensitive data)
_ = try db.prepare(varQuery3, ["id": id, "number": mobilePhoneNumber]).run() // BAD (sensitive data)
_ = try db.run(varQuery3, ["id": id, "number": mobilePhoneNumber]) // BAD (sensitive data)
_ = try db.scalar(varQuery3, ["id": id, "number": mobilePhoneNumber]) // BAD (sensitive data)
let stmt3 = try db.prepare(varQuery3) // GOOD
_ = try stmt3.bind(["id": id, "number": mobilePhoneNumber]).run() // $ Alert // BAD (sensitive data)
_ = try stmt3.run(["id": id, "number": mobilePhoneNumber]) // $ Alert // BAD (sensitive data)
_ = try stmt3.scalar(["id": id, "number": mobilePhoneNumber]) // $ Alert // BAD (sensitive data)
_ = try stmt3.bind(["id": id, "number": mobilePhoneNumber]).run() // BAD (sensitive data)
_ = try stmt3.run(["id": id, "number": mobilePhoneNumber]) // BAD (sensitive data)
_ = try stmt3.scalar(["id": id, "number": mobilePhoneNumber]) // BAD (sensitive data)
// --- higher level insert / update ---
@@ -183,20 +183,20 @@ func test_sqlite_swift_api(db: Connection, id: Int, mobilePhoneNumber: String) t
let filter = table.filter(idExpr == id) // GOOD
try db.run(table.insert(idExpr <- id, numberExpr <- "123")) // GOOD
try db.run(table.insert(idExpr <- id, numberExpr <- mobilePhoneNumber)) // $ Alert // BAD (sensitive data)
try db.run(table.insert(idExpr <- id, numberExpr <- mobilePhoneNumber)) // BAD (sensitive data)
try db.run(table.update(numberExpr <- "123")) // GOOD
try db.run(table.update(numberExpr <- mobilePhoneNumber)) // $ Alert // BAD (sensitive data)
try db.run(table.update(numberExpr <- mobilePhoneNumber)) // BAD (sensitive data)
try db.run(filter.update(numberExpr <- "123")) // GOOD
try db.run(filter.update(numberExpr <- mobilePhoneNumber)) // $ Alert // BAD (sensitive data)
try db.run(filter.update(numberExpr <- mobilePhoneNumber)) // BAD (sensitive data)
try db.run(table.update(numberExpr <- numberExpr.replace("123", with: "456"))) // GOOD
try db.run(table.update(numberExpr <- numberExpr.replace("123", with: mobilePhoneNumber))) // $ Alert // BAD (sensitive data)
try db.run(table.update(numberExpr <- numberExpr.replace("123", with: mobilePhoneNumber))) // BAD (sensitive data)
// (much more complex query construction is possible in SQLite.swift)
let goodMany = [[numberExpr <- "456"]]
let badMany = [[numberExpr <- mobilePhoneNumber]] // $ Source
let badMany = [[numberExpr <- mobilePhoneNumber]]
try db.run(table.insertMany(goodMany)) // GOOD
try db.run(table.insertMany(badMany)) // $ Alert // BAD (sensitive data)
try db.run(table.insertMany(badMany)) // BAD (sensitive data)
try db.run(table.insertMany(or: OnConflict.replace, goodMany)) // GOOD
try db.run(table.insertMany(or: OnConflict.replace, badMany)) // $ Alert // BAD (sensitive data)
try db.run(table.insertMany(or: OnConflict.replace, badMany)) // BAD (sensitive data)
}

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));" // $ Source
let updateQuery = "UPDATE PATIENTS SET NOTES=\(medicalNotes) WHERE ID=\(id);" // $ Source
let insertQuery = "INSERT INTO PATIENTS(ID, NOTES) VALUES(\(id), \(medicalNotes));"
let updateQuery = "UPDATE PATIENTS SET NOTES=\(medicalNotes) WHERE ID=\(id);"
let deleteQuery = "DELETE FROM PATIENTS WHERE ID=\(id);"
let _ = sqlite3_exec(db, insertQuery, nil, nil, nil) // $ Alert // BAD (sensitive data)
let _ = sqlite3_exec(db, updateQuery, nil, nil, nil) // $ Alert // BAD (sensitive data)
let _ = sqlite3_exec(db, insertQuery, nil, nil, nil) // BAD (sensitive data)
let _ = sqlite3_exec(db, updateQuery, nil, nil, nil) // BAD (sensitive data)
let _ = sqlite3_exec(db, deleteQuery, nil, nil, nil) // GOOD
// --- sensitive data in bindings ---
@@ -55,7 +55,7 @@ func test_sqlite3_c_api(db: OpaquePointer?, id: Int32, medicalNotes: String) {
if (sqlite3_prepare(db, varQuery, -1, &stmt1, nil) == SQLITE_OK) { // GOOD
if (sqlite3_bind_int(stmt1, 1, id) == SQLITE_OK) { // GOOD
if (sqlite3_bind_text(stmt1, 2, medicalNotes, -1, SQLITE_TRANSIENT) == SQLITE_OK) { // $ Alert // BAD (sensitive data)
if (sqlite3_bind_text(stmt1, 2, medicalNotes, -1, SQLITE_TRANSIENT) == SQLITE_OK) { // BAD (sensitive data)
// ...
}
}

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

View File

@@ -16,7 +16,7 @@ class NSManagedObject : NSObject
class MyManagedObject : NSManagedObject
{
func setIndirect(value: String) {
setValue(value, forKey: "myKey") // $ Alert
setValue(value, forKey: "myKey")
}
var myValue: String {
@@ -29,7 +29,7 @@ class MyManagedObject : NSManagedObject
}
}
set {
setValue(newValue, forKey: "myKey") // $ Alert // [additional result reported here]
setValue(newValue, forKey: "myKey") // [additional result reported here]
}
}
}
@@ -45,23 +45,23 @@ func doSomething(password: String) { }
func test1(obj : NSManagedObject, password : String, password_hash : String) {
// NSManagedObject methods...
obj.setValue(password, forKey: "myKey") // $ Alert
obj.setValue(password, forKey: "myKey") // BAD
obj.setValue(password_hash, forKey: "myKey") // GOOD (not sensitive)
obj.setPrimitiveValue(password, forKey: "myKey") // $ Alert
obj.setPrimitiveValue(password, forKey: "myKey") // BAD
obj.setPrimitiveValue(password_hash, forKey: "myKey") // GOOD (not sensitive)
}
func test2(obj : MyManagedObject, password : String, password_file : String) {
// MyManagedObject methods...
obj.setValue(password, forKey: "myKey") // $ Alert
obj.setValue(password, forKey: "myKey") // BAD
obj.setValue(password_file, forKey: "myKey") // GOOD (not sensitive)
obj.setIndirect(value: password) // $ Source // BAD [reported on line 19]
obj.setIndirect(value: password) // BAD [reported on line 19]
obj.setIndirect(value: password_file) // GOOD (not sensitive)
obj.myValue = password // $ Alert Source // BAD [also reported on line 32]
obj.myValue = password // BAD [also reported on line 32]
obj.myValue = password_file // GOOD (not sensitive)
}
@@ -74,27 +74,27 @@ func test3(obj : NSManagedObject, x : String) {
// alternative evidence of sensitivity...
obj.setValue(x, forKey: "myKey") // BAD [NOT REPORTED]
doSomething(password: x); // $ Source
obj.setValue(x, forKey: "myKey") // $ Alert
doSomething(password: x);
obj.setValue(x, forKey: "myKey") // BAD
let y = getPassword(); // $ Source
obj.setValue(y, forKey: "myKey") // $ Alert
let y = getPassword();
obj.setValue(y, forKey: "myKey") // BAD
let z = MyClass()
obj.setValue(z.harmless, forKey: "myKey") // GOOD (not sensitive)
obj.setValue(z.password, forKey: "myKey") // $ Alert
obj.setValue(z.password, forKey: "myKey") // BAD
}
func test4(obj : NSManagedObject, passwd : String) {
// sanitizers...
var x = passwd; // $ Source
var y = passwd; // $ Source
var z = passwd; // $ Source
var x = passwd;
var y = passwd;
var z = passwd;
obj.setValue(x, forKey: "myKey") // $ Alert
obj.setValue(y, forKey: "myKey") // $ Alert
obj.setValue(z, forKey: "myKey") // $ Alert
obj.setValue(x, forKey: "myKey") // BAD
obj.setValue(y, forKey: "myKey") // BAD
obj.setValue(z, forKey: "myKey") // BAD
x = encrypt(x);
hash(data: &y);
@@ -125,8 +125,8 @@ func test5(obj : NSManagedObject) {
// more variants...
obj.setValue(createSecureKey(), forKey: "myKey") // BAD [NOT DETECTED]
obj.setValue(generateSecretKey(), forKey: "myKey") // $ Alert
obj.setValue(getCertificate(), forKey: "myKey") // $ Alert
obj.setValue(generateSecretKey(), forKey: "myKey") // BAD
obj.setValue(getCertificate(), forKey: "myKey") // BAD
let gen = KeyGen()
let v = gen.generate()

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

View File

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

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 // $ Alert
a.data = myPassword // BAD
realm.add(a)
let b = MyRealmSwiftObject()
@@ -46,7 +46,7 @@ func test1(realm : Realm, myHarmless: String, myPassword : String, myHashedPassw
realm.add(b) // GOOD (not sensitive)
let c = MyRealmSwiftObject()
c.data = myPassword // $ Alert
c.data = myPassword // BAD
realm.create(MyRealmSwiftObject.self, value: c)
let d = MyRealmSwiftObject()
@@ -56,21 +56,21 @@ func test1(realm : Realm, myHarmless: String, myPassword : String, myHashedPassw
// retrieve objects ...
var e = realm.object(ofType: MyRealmSwiftObject.self, forPrimaryKey: "key")
e!.data = myPassword // $ Alert
e!.data = myPassword // BAD
var f = realm.object(ofType: MyRealmSwiftObject.self, forPrimaryKey: "key")
f!.data = myHashedPassword // GOOD (not sensitive)
let g = MyRealmSwiftObject()
g.data = "" // GOOD (not sensitive)
g.data = myPassword // $ Alert
g.data = myPassword // BAD
g.data = "" // GOOD (not sensitive)
// MyRealmSwiftObject2...
let h = MyRealmSwiftObject2()
h.harmless = myHarmless // GOOD (not sensitive)
h.password = myPassword // $ Alert
h.password = myPassword // BAD
realm.add(h)
}

View File

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

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

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); // $ Alert
_ = URL(string: "http://example.com/login?p=" + passwd); // BAD
_ = URL(string: "http://example.com/login?p=" + encrypted_passwd); // GOOD (not sensitive)
_ = URL(string: "http://example.com/login?ac=" + account_no); // $ Alert
_ = URL(string: "http://example.com/login?cc=" + credit_card_no); // $ Alert
_ = URL(string: "http://example.com/login?ac=" + account_no); // BAD
_ = URL(string: "http://example.com/login?cc=" + credit_card_no); // BAD
let base = URL(string: "http://example.com/"); // GOOD (not sensitive)
_ = URL(string: "abc", relativeTo: base); // GOOD (not sensitive)
let f = URL(string: passwd, relativeTo: base); // $ Alert
let f = URL(string: passwd, relativeTo: base); // BAD
_ = URL(string: "abc", relativeTo: f); // BAD (reported on line above)
let e_mail = myString
_ = URL(string: "http://example.com/login?em=" + e_mail); // $ Alert
_ = URL(string: "http://example.com/login?em=" + e_mail); // BAD
let a_homeaddr_z = getMyString()
_ = URL(string: "http://example.com/login?home=" + a_homeaddr_z); // $ Alert
_ = URL(string: "http://example.com/login?home=" + a_homeaddr_z); // BAD
let resident_ID = getMyString()
_ = URL(string: "http://example.com/login?id=" + resident_ID); // $ Alert
_ = URL(string: "http://example.com/login?id=" + resident_ID); // BAD
}
func get_private_key() -> String { return "" }
@@ -70,9 +70,9 @@ func test2() {
_ = URL(string: "http://example.com/login?key=" + get_aes_key()); // BAD [NOT DETECTED]
_ = URL(string: "http://example.com/login?key=" + get_aws_key()); // BAD [NOT DETECTED]
_ = URL(string: "http://example.com/login?key=" + get_access_key()); // BAD [NOT DETECTED]
_ = URL(string: "http://example.com/login?key=" + get_secret_key()); // $ Alert
_ = URL(string: "http://example.com/login?key=" + get_secret_key()); // BAD
_ = URL(string: "http://example.com/login?key=" + get_key_press()); // GOOD (not sensitive)
_ = URL(string: "http://example.com/login?cert=" + get_cert_string()); // $ Alert
_ = URL(string: "http://example.com/login?cert=" + get_cert_string()); // BAD
_ = URL(string: "http://example.com/login?certain=" + get_certain()); // GOOD (not sensitive)
}
@@ -93,7 +93,7 @@ func test3() {
_ = URL(string: "http://example.com/login?key=\(priv_key)"); // BAD [NOT DETECTED]
_ = URL(string: "http://example.com/login?key=\(private_key)"); // BAD [NOT DETECTED]
_ = URL(string: "http://example.com/login?key=\(pub_key)"); // GOOD (not sensitive)
_ = URL(string: "http://example.com/login?cert=\(certificate)"); // $ Alert
_ = URL(string: "http://example.com/login?cert=\(certificate)"); // BAD
_ = URL(string: "http://example.com/login?tok=\(secure_token)"); // BAD [NOT DETECTED]
_ = URL(string: "http://example.com/login?tok=\(access_token)"); // BAD [NOT DETECTED]
_ = URL(string: "http://example.com/login?tok=\(auth_token)"); // BAD [NOT DETECTED]
@@ -101,9 +101,9 @@ func test3() {
}
func test4(key: SecKey) {
if let data = SecKeyCopyExternalRepresentation(key, nil) as? Data { // $ Source
if let data = SecKeyCopyExternalRepresentation(key, nil) as? Data {
if let string = String(data: data, encoding: .utf8) {
_ = URL(string: "http://example.com/login?tok=\(string)"); // $ Alert
_ = URL(string: "http://example.com/login?tok=\(string)"); // BAD
}
}
}
@@ -113,14 +113,14 @@ func test5() {
let email = get_string()
let secret_key = get_string()
_ = URL(string: "http://example.com/login?email=\(email)"); // $ Alert
_ = URL(string: "http://example.com/login?email=\(email)"); // BAD
_ = URL(string: "mailto:\(email)"); // GOOD (revealing your e-amil address in an e-mail is expected)
_ = URL(string: "mailto:info@example.com?subject=\(secret_key)"); // BAD [NOT DETECTED]
_ = URL(string: "mailto:info@example.com?subject=foo&cc=\(email)"); // GOOD
let phone_number = get_string()
_ = URL(string: "http://example.com/profile?tel=\(phone_number)"); // $ Alert
_ = URL(string: "http://example.com/profile?tel=\(phone_number)"); // BAD
_ = URL(string: "tel:\(phone_number)") // GOOD
_ = URL(string: "telprompt:\(phone_number)") // GOOD
_ = URL(string: "callto:\(phone_number)") // GOOD
@@ -129,5 +129,5 @@ func test5() {
let account_no = get_string()
_ = URL(string: "file:///foo/bar/\(account_no).csv") // GOOD (local, so not transmitted)
_ = URL(string: "ftp://example.com/\(account_no).csv") // $ Alert
_ = URL(string: "ftp://example.com/\(account_no).csv") // BAD
}

View File

@@ -1,2 +1 @@
query: queries/Security/CWE-312/CleartextStoragePreferences.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
queries/Security/CWE-312/CleartextStoragePreferences.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") // $ Alert
store.set(password, forKey: "myKey") // BAD
store.set(passwordHash, forKey: "myKey") // GOOD (not sensitive)
}
@@ -38,27 +38,27 @@ func test3(x: String) {
// alternative evidence of sensitivity...
NSUbiquitousKeyValueStore.default.set(x, forKey: "myKey") // BAD [NOT REPORTED]
doSomething(password: x); // $ Source
NSUbiquitousKeyValueStore.default.set(x, forKey: "myKey") // $ Alert
doSomething(password: x);
NSUbiquitousKeyValueStore.default.set(x, forKey: "myKey") // BAD
let y = getPassword(); // $ Source
NSUbiquitousKeyValueStore.default.set(y, forKey: "myKey") // $ Alert
let y = getPassword();
NSUbiquitousKeyValueStore.default.set(y, forKey: "myKey") // BAD
let z = MyClass()
NSUbiquitousKeyValueStore.default.set(z.harmless, forKey: "myKey") // GOOD (not sensitive)
NSUbiquitousKeyValueStore.default.set(z.password, forKey: "myKey") // $ Alert
NSUbiquitousKeyValueStore.default.set(z.password, forKey: "myKey") // BAD
}
func test4(passwd: String) {
// sanitizers...
var x = passwd; // $ Source
var y = passwd; // $ Source
var z = passwd; // $ Source
var x = passwd;
var y = passwd;
var z = passwd;
NSUbiquitousKeyValueStore.default.set(x, forKey: "myKey") // $ Alert
NSUbiquitousKeyValueStore.default.set(y, forKey: "myKey") // $ Alert
NSUbiquitousKeyValueStore.default.set(z, forKey: "myKey") // $ Alert
NSUbiquitousKeyValueStore.default.set(x, forKey: "myKey") // BAD
NSUbiquitousKeyValueStore.default.set(y, forKey: "myKey") // BAD
NSUbiquitousKeyValueStore.default.set(z, forKey: "myKey") // BAD
x = encrypt(x);
hash(data: &y);

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

View File

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

View File

@@ -36,7 +36,7 @@ func getRandomArray() -> Array<UInt8> {
}
func getECBBlockMode() -> BlockMode {
return ECB() // $ Source
return ECB()
}
func getCBCBlockMode() -> BlockMode {
@@ -47,18 +47,18 @@ func getCBCBlockMode() -> BlockMode {
func test1() {
let key: Array<UInt8> = [0x2a, 0x3a, 0x80, 0x05, 0xaf, 0x46, 0x58, 0x2d, 0x66, 0x52, 0x10, 0xae, 0x86, 0xd3, 0x8e, 0x8f]
let ecb = ECB() // $ Source
let ecb = ECB()
let iv = getRandomArray()
let cbc = CBC(iv: iv)
let padding = Padding.noPadding
// AES test cases
let ab1 = AES(key: key, blockMode: ecb, padding: padding) // $ Alert
let ab2 = AES(key: key, blockMode: ecb) // $ Alert
let ab3 = AES(key: key, blockMode: ECB(), padding: padding) // $ Alert
let ab4 = AES(key: key, blockMode: ECB()) // $ Alert
let ab5 = AES(key: key, blockMode: getECBBlockMode(), padding: padding) // $ Alert
let ab6 = AES(key: key, blockMode: getECBBlockMode()) // $ Alert
let ab1 = AES(key: key, blockMode: ecb, padding: padding) // BAD
let ab2 = AES(key: key, blockMode: ecb) // BAD
let ab3 = AES(key: key, blockMode: ECB(), padding: padding) // BAD
let ab4 = AES(key: key, blockMode: ECB()) // BAD
let ab5 = AES(key: key, blockMode: getECBBlockMode(), padding: padding) // BAD
let ab6 = AES(key: key, blockMode: getECBBlockMode()) // BAD
let ag1 = AES(key: key, blockMode: cbc, padding: padding) // GOOD
let ag2 = AES(key: key, blockMode: cbc) // GOOD
@@ -68,9 +68,9 @@ func test1() {
let ag6 = AES(key: key, blockMode: getCBCBlockMode()) // GOOD
// Blowfish test cases
let bb1 = Blowfish(key: key, blockMode: ecb, padding: padding) // $ Alert
let bb2 = Blowfish(key: key, blockMode: ECB(), padding: padding) // $ Alert
let bb3 = Blowfish(key: key, blockMode: getECBBlockMode(), padding: padding) // $ Alert
let bb1 = Blowfish(key: key, blockMode: ecb, padding: padding) // BAD
let bb2 = Blowfish(key: key, blockMode: ECB(), padding: padding) // BAD
let bb3 = Blowfish(key: key, blockMode: getECBBlockMode(), padding: padding) // BAD
let bg1 = Blowfish(key: key, blockMode: cbc, padding: padding) // GOOD
let bg2 = Blowfish(key: key, blockMode: CBC(iv: iv), padding: padding) // GOOD

View File

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

View File

@@ -1,2 +1 @@
query: queries/Security/CWE-328/WeakSensitiveDataHashing.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
queries/Security/CWE-328/WeakSensitiveDataHashing.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) // $ Alert
hash = Crypto.Insecure.MD5.hash(bufferPointer: passwd) // $ Alert
hash = Crypto.Insecure.MD5.hash(data: cert) // $ Alert
var hash = Crypto.Insecure.MD5.hash(data: passwd) // BAD
hash = Crypto.Insecure.MD5.hash(bufferPointer: passwd) // BAD
hash = Crypto.Insecure.MD5.hash(data: cert) // BAD
hash = Crypto.Insecure.MD5.hash(data: encrypted_passwd) // GOOD (not sensitive)
hash = Crypto.Insecure.MD5.hash(data: account_no) // $ Alert
hash = Crypto.Insecure.MD5.hash(data: credit_card_no) // $ Alert
hash = Crypto.Insecure.MD5.hash(data: account_no) // BAD
hash = Crypto.Insecure.MD5.hash(data: credit_card_no) // BAD
hash = Insecure.MD5.hash(data: passwd) // $ Alert
hash = Insecure.MD5.hash(bufferPointer: passwd) // $ Alert
hash = Insecure.MD5.hash(data: cert) // $ Alert
hash = Insecure.MD5.hash(data: passwd) // BAD
hash = Insecure.MD5.hash(bufferPointer: passwd) // BAD
hash = Insecure.MD5.hash(data: cert) // BAD
hash = Insecure.MD5.hash(data: encrypted_passwd) // GOOD (not sensitive)
hash = Insecure.MD5.hash(data: account_no) // $ Alert
hash = Insecure.MD5.hash(data: credit_card_no) // $ Alert
hash = Insecure.MD5.hash(data: account_no) // BAD
hash = Insecure.MD5.hash(data: credit_card_no) // BAD
hash = Crypto.Insecure.SHA1.hash(data: passwd) // $ Alert
hash = Crypto.Insecure.SHA1.hash(bufferPointer: passwd) // $ Alert
hash = Crypto.Insecure.SHA1.hash(data: cert) // $ Alert
hash = Crypto.Insecure.SHA1.hash(data: passwd) // BAD
hash = Crypto.Insecure.SHA1.hash(bufferPointer: passwd) // BAD
hash = Crypto.Insecure.SHA1.hash(data: cert) // BAD
hash = Crypto.Insecure.SHA1.hash(data: encrypted_passwd) // GOOD (not sensitive)
hash = Crypto.Insecure.SHA1.hash(data: account_no) // $ Alert
hash = Crypto.Insecure.SHA1.hash(data: credit_card_no) // $ Alert
hash = Crypto.Insecure.SHA1.hash(data: account_no) // BAD
hash = Crypto.Insecure.SHA1.hash(data: credit_card_no) // BAD
hash = Crypto.SHA256.hash(data: passwd) // $ Alert // BAD, not a computationally expensive hash
hash = Crypto.SHA256.hash(bufferPointer: passwd) // $ Alert // BAD, not a computationally expensive hash
hash = Crypto.SHA256.hash(data: passwd) // BAD, not a computationally expensive hash
hash = Crypto.SHA256.hash(bufferPointer: passwd) // BAD, not a computationally expensive hash
hash = Crypto.SHA256.hash(data: cert) // GOOD, computationally expensive hash not required
hash = Crypto.SHA256.hash(data: encrypted_passwd) // GOOD, not sensitive
hash = Crypto.SHA256.hash(data: account_no) // GOOD, computationally expensive hash not required
hash = Crypto.SHA256.hash(data: credit_card_no) // GOOD, computationally expensive hash not required
hash = Crypto.SHA384.hash(data: passwd) // $ Alert // BAD, not a computationally expensive hash
hash = Crypto.SHA384.hash(bufferPointer: passwd) // $ Alert // BAD, not a computationally expensive hash
hash = Crypto.SHA384.hash(data: passwd) // BAD, not a computationally expensive hash
hash = Crypto.SHA384.hash(bufferPointer: passwd) // BAD, not a computationally expensive hash
hash = Crypto.SHA384.hash(data: cert) // GOOD, computationally expensive hash not required
hash = Crypto.SHA384.hash(data: encrypted_passwd) // GOOD, not sensitive
hash = Crypto.SHA384.hash(data: account_no) // GOOD, computationally expensive hash not required
hash = Crypto.SHA384.hash(data: credit_card_no) // GOOD, computationally expensive hash not required
hash = Crypto.SHA512.hash(data: passwd) // $ Alert // BAD, not a computationally expensive hash
hash = Crypto.SHA512.hash(bufferPointer: passwd) // $ Alert // BAD, not a computationally expensive hash
hash = Crypto.SHA512.hash(data: passwd) // BAD, not a computationally expensive hash
hash = Crypto.SHA512.hash(bufferPointer: passwd) // BAD, not a computationally expensive hash
hash = Crypto.SHA512.hash(data: cert) // GOOD, computationally expensive hash not required
hash = Crypto.SHA512.hash(data: encrypted_passwd) // GOOD, not sensitive
hash = Crypto.SHA512.hash(data: account_no) // GOOD, computationally expensive hash not required
@@ -126,25 +126,25 @@ func testHashMethods(passwd : UnsafeRawBufferPointer, cert: String, encrypted_pa
func testMD5UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) {
var hash = Crypto.Insecure.MD5()
hash.update(data: passwd) // $ Alert
hash.update(data: cert) // $ Alert
hash.update(data: passwd) // BAD
hash.update(data: cert) // BAD
hash.update(data: encrypted_passwd) // GOOD (not sensitive)
hash.update(data: account_no) // $ Alert
hash.update(data: credit_card_no) // $ Alert
hash.update(data: account_no) // BAD
hash.update(data: credit_card_no) // BAD
}
func testSHA1UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) {
var hash = Crypto.Insecure.SHA1()
hash.update(data: passwd) // $ Alert
hash.update(data: cert) // $ Alert
hash.update(data: passwd) // BAD
hash.update(data: cert) // BAD
hash.update(data: encrypted_passwd) // GOOD (not sensitive)
hash.update(data: account_no) // $ Alert
hash.update(data: credit_card_no) // $ Alert
hash.update(data: account_no) // BAD
hash.update(data: credit_card_no) // BAD
}
func testSHA256UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) {
var hash = Crypto.SHA256()
hash.update(data: passwd) // $ Alert // BAD, not a computationally expensive hash
hash.update(data: passwd) // BAD, not a computationally expensive hash
hash.update(data: cert) // GOOD
hash.update(data: encrypted_passwd) // GOOD (not sensitive)
hash.update(data: account_no) // GOOD
@@ -153,7 +153,7 @@ func testSHA256UpdateWithData(passwd : String, cert: String, encrypted_passwd :
func testSHA384UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) {
var hash = Crypto.SHA384()
hash.update(data: passwd) // $ Alert // BAD, not a computationally expensive hash
hash.update(data: passwd) // BAD, not a computationally expensive hash
hash.update(data: cert) // GOOD
hash.update(data: encrypted_passwd) // GOOD (not sensitive)
hash.update(data: account_no) // GOOD
@@ -162,7 +162,7 @@ func testSHA384UpdateWithData(passwd : String, cert: String, encrypted_passwd :
func testSHA512UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) {
var hash = Crypto.SHA512()
hash.update(data: passwd) // $ Alert // BAD, not a computationally expensive hash
hash.update(data: passwd) // BAD, not a computationally expensive hash
hash.update(data: cert) // GOOD
hash.update(data: encrypted_passwd) // GOOD (not sensitive)
hash.update(data: account_no) // GOOD
@@ -171,25 +171,25 @@ func testSHA512UpdateWithData(passwd : String, cert: String, encrypted_passwd :
func testMD5UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer, cert: UnsafeRawBufferPointer, encrypted_passwd : UnsafeRawBufferPointer, account_no : UnsafeRawBufferPointer, credit_card_no : UnsafeRawBufferPointer) {
var hash = Crypto.Insecure.MD5()
hash.update(bufferPointer: passwd) // $ Alert
hash.update(bufferPointer: cert) // $ Alert
hash.update(bufferPointer: passwd) // BAD
hash.update(bufferPointer: cert) // BAD
hash.update(bufferPointer: encrypted_passwd) // GOOD (not sensitive)
hash.update(bufferPointer: account_no) // $ Alert
hash.update(bufferPointer: credit_card_no) // $ Alert
hash.update(bufferPointer: account_no) // BAD
hash.update(bufferPointer: credit_card_no) // BAD
}
func testSHA1UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer, cert: UnsafeRawBufferPointer, encrypted_passwd : UnsafeRawBufferPointer, account_no : UnsafeRawBufferPointer, credit_card_no : UnsafeRawBufferPointer) {
var hash = Crypto.Insecure.SHA1()
hash.update(bufferPointer: passwd) // $ Alert
hash.update(bufferPointer: cert) // $ Alert
hash.update(bufferPointer: passwd) // BAD
hash.update(bufferPointer: cert) // BAD
hash.update(bufferPointer: encrypted_passwd) // GOOD (not sensitive)
hash.update(bufferPointer: account_no) // $ Alert
hash.update(bufferPointer: credit_card_no) // $ Alert
hash.update(bufferPointer: account_no) // BAD
hash.update(bufferPointer: credit_card_no) // BAD
}
func testSHA256UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer, cert: UnsafeRawBufferPointer, encrypted_passwd : UnsafeRawBufferPointer, account_no : UnsafeRawBufferPointer, credit_card_no : UnsafeRawBufferPointer) {
var hash = Crypto.SHA256()
hash.update(bufferPointer: passwd) // $ Alert // BAD, not a computationally expensive hash
hash.update(bufferPointer: passwd) // BAD, not a computationally expensive hash
hash.update(bufferPointer: cert) // GOOD
hash.update(bufferPointer: encrypted_passwd) // GOOD (not sensitive)
hash.update(bufferPointer: account_no) // GOOD
@@ -198,7 +198,7 @@ func testSHA256UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer,
func testSHA384UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer, cert: UnsafeRawBufferPointer, encrypted_passwd : UnsafeRawBufferPointer, account_no : UnsafeRawBufferPointer, credit_card_no : UnsafeRawBufferPointer) {
var hash = Crypto.SHA384()
hash.update(bufferPointer: passwd) // $ Alert // BAD, not a computationally expensive hash
hash.update(bufferPointer: passwd) // BAD, not a computationally expensive hash
hash.update(bufferPointer: cert) // GOOD
hash.update(bufferPointer: encrypted_passwd) // GOOD (not sensitive)
hash.update(bufferPointer: account_no) // GOOD
@@ -207,7 +207,7 @@ func testSHA384UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer,
func testSHA512UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer, cert: UnsafeRawBufferPointer, encrypted_passwd : UnsafeRawBufferPointer, account_no : UnsafeRawBufferPointer, credit_card_no : UnsafeRawBufferPointer) {
var hash = Crypto.SHA512()
hash.update(bufferPointer: passwd) // $ Alert // BAD, not a computationally expensive hash
hash.update(bufferPointer: passwd) // BAD, not a computationally expensive hash
hash.update(bufferPointer: cert) // GOOD
hash.update(bufferPointer: encrypted_passwd) // GOOD (not sensitive)
hash.update(bufferPointer: account_no) // GOOD
@@ -217,30 +217,30 @@ func testSHA512UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer,
func testBadExample(passwordString: String) {
// this is the "bad" example from the .qhelp
let passwordData = Data(passwordString.utf8)
let passwordHash = Crypto.SHA512.hash(data: passwordData) // $ Alert // BAD, not a computationally expensive hash
let passwordHash = Crypto.SHA512.hash(data: passwordData) // BAD, not a computationally expensive hash
// ...
if Crypto.SHA512.hash(data: Data(passwordString.utf8)) == passwordHash { // $ Alert // BAD, not a computationally expensive hash
if Crypto.SHA512.hash(data: Data(passwordString.utf8)) == passwordHash { // BAD, not a computationally expensive hash
// ...
}
}
func testWithFlowAndMetatypes(cardNumber: String) {
let value1 = Data(cardNumber.utf8); // $ Source
let _digest1 = Insecure.MD5.hash(data: value1); // $ Alert
let value1 = Data(cardNumber.utf8);
let _digest1 = Insecure.MD5.hash(data: value1); // BAD
let value2 = Data(cardNumber.utf8); // $ Source
let value2 = Data(cardNumber.utf8);
let hasher2 = Insecure.MD5.self; // metatype
let _digest2 = hasher2.hash(data: value2); // $ Alert
let _digest2 = hasher2.hash(data: value2); // BAD
let value3 = Data(cardNumber.utf8); // $ Source
let _digest3 = (Insecure.MD5.self).hash(data: value3); // $ Alert
let value3 = Data(cardNumber.utf8);
let _digest3 = (Insecure.MD5.self).hash(data: value3); // BAD
let value4 = Data(cardNumber.utf8); // $ Source
let value4 = Data(cardNumber.utf8);
testReceiver1(value: value4);
let value5 = Data(cardNumber.utf8); // $ Source
let value5 = Data(cardNumber.utf8);
testReceiver2(hasher: Insecure.MD5.self, value: value5);
let value6 = Data(cardNumber.utf8);
@@ -248,11 +248,11 @@ func testWithFlowAndMetatypes(cardNumber: String) {
}
func testReceiver1(value: Data) {
let _digest = Insecure.MD5.hash(data: value); // $ Alert
let _digest = Insecure.MD5.hash(data: value); // BAD
}
func testReceiver2(hasher: Insecure.MD5.Type, value: Data) {
let _digest = hasher.hash(data: value); // $ Alert
let _digest = hasher.hash(data: value); // BAD
}
func testReceiver3<H: HashFunction>(hasher: H.Type, value: Data) {

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

View File

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

View File

@@ -1,2 +1 @@
query: queries/Security/CWE-760/ConstantSalt.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
queries/Security/CWE-760/ConstantSalt.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") // $ Source
let myConstantSalt2 = Data(0) // $ Source
let myConstantSalt1 = Data("abcdef123456")
let myConstantSalt2 = Data(0)
let _ = myEncryptor.key(forPassword: myPassword, salt: myRandomSalt1, settings: myKeyDerivationSettings) // GOOD
let _ = myEncryptor.key(forPassword: myPassword, salt: myConstantSalt1, settings: myKeyDerivationSettings) // $ Alert
let _ = myEncryptor.key(forPassword: myPassword, salt: myConstantSalt1, settings: myKeyDerivationSettings) // BAD
let _ = myEncryptor.keyForPassword(myPassword, salt: myRandomSalt2, settings: myKeyDerivationSettings) // GOOD
let _ = myEncryptor.keyForPassword(myPassword, salt: myConstantSalt2, settings: myKeyDerivationSettings) // $ Alert
let _ = myEncryptor.keyForPassword(myPassword, salt: myConstantSalt2, settings: myKeyDerivationSettings) // BAD
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, iv: myIV, encryptionSalt: myRandomSalt1, hmacSalt: myRandomSalt2, handler: myHandler) // GOOD
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, iv: myIV, encryptionSalt: myConstantSalt1, hmacSalt: myRandomSalt2, handler: myHandler) // $ Alert
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, iv: myIV, encryptionSalt: myRandomSalt1, hmacSalt: myConstantSalt2, handler: myHandler) // $ Alert
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, iv: myIV, encryptionSalt: myConstantSalt1, hmacSalt: myRandomSalt2, handler: myHandler) // BAD
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, iv: myIV, encryptionSalt: myRandomSalt1, hmacSalt: myConstantSalt2, handler: myHandler) // BAD
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, IV: myIV, encryptionSalt: myRandomSalt1, HMACSalt: myRandomSalt2, handler: myHandler) // GOOD
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, IV: myIV, encryptionSalt: myConstantSalt1, HMACSalt: myRandomSalt2, handler: myHandler) // $ Alert
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, IV: myIV, encryptionSalt: myRandomSalt1, HMACSalt: myConstantSalt2, handler: myHandler) // $ Alert
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, IV: myIV, encryptionSalt: myConstantSalt1, HMACSalt: myRandomSalt2, handler: myHandler) // BAD
let _ = RNEncryptor(settings: kRNCryptorAES256Settings, password: myPassword, IV: myIV, encryptionSalt: myRandomSalt1, HMACSalt: myConstantSalt2, handler: myHandler) // BAD
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myPassword, iv: myIV, encryptionSalt: myRandomSalt1, hmacSalt: myRandomSalt2) // GOOD
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myPassword, iv: myIV, encryptionSalt: myConstantSalt1, hmacSalt: myRandomSalt2) // $ Alert
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myPassword, iv: myIV, encryptionSalt: myRandomSalt1, hmacSalt: myConstantSalt2) // $ Alert
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myPassword, iv: myIV, encryptionSalt: myConstantSalt1, hmacSalt: myRandomSalt2) // BAD
let _ = try? myEncryptor.encryptData(myData, with: kRNCryptorAES256Settings, password: myPassword, iv: myIV, encryptionSalt: myRandomSalt1, hmacSalt: myConstantSalt2) // BAD
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, password: myPassword, IV: myIV, encryptionSalt: myRandomSalt1, HMACSalt: myRandomSalt2) // GOOD
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, password: myPassword, IV: myIV, encryptionSalt: myConstantSalt1, HMACSalt: myRandomSalt2) // $ Alert
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, password: myPassword, IV: myIV, encryptionSalt: myRandomSalt1, HMACSalt: myConstantSalt2) // $ Alert
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, password: myPassword, IV: myIV, encryptionSalt: myConstantSalt1, HMACSalt: myRandomSalt2) // BAD
let _ = try? myEncryptor.encryptData(myData, withSettings: kRNCryptorAES256Settings, password: myPassword, IV: myIV, encryptionSalt: myRandomSalt1, HMACSalt: myConstantSalt2) // BAD
// appending constants
let _ = myEncryptor.key(forPassword: myPassword, salt: Data(getARandomString() + getARandomString()), settings: myKeyDerivationSettings) // GOOD

View File

@@ -26,7 +26,7 @@ final class Scrypt {
// Helper functions
func getConstantString() -> String {
"this string is constant" // $ Source
"this string is constant"
}
func getConstantArray() -> Array<UInt8> {
@@ -40,7 +40,7 @@ func getRandomArray() -> Array<UInt8> {
// --- tests ---
func test() {
let constantSalt: Array<UInt8> = [0x2a, 0x3a, 0x80, 0x05, 0xaf, 0x46, 0x58, 0x2d, 0x66, 0x52, 0x10, 0xae, 0x86, 0xd3, 0x8e, 0x8f] // $ Source
let constantSalt: Array<UInt8> = [0x2a, 0x3a, 0x80, 0x05, 0xaf, 0x46, 0x58, 0x2d, 0x66, 0x52, 0x10, 0xae, 0x86, 0xd3, 0x8e, 0x8f]
let constantStringSalt = getConstantArray()
let randomSalt = getRandomArray()
let randomArray = getRandomArray()
@@ -48,23 +48,23 @@ func test() {
let iterations = 120120
// HKDF test cases
let hkdfb1 = HKDF(password: randomArray, salt: constantSalt, info: randomArray, keyLength: 0, variant: variant) // $ Alert
let hkdfb2 = HKDF(password: randomArray, salt: constantStringSalt, info: randomArray, keyLength: 0, variant: variant) // $ Alert
let hkdfb1 = HKDF(password: randomArray, salt: constantSalt, info: randomArray, keyLength: 0, variant: variant) // BAD
let hkdfb2 = HKDF(password: randomArray, salt: constantStringSalt, info: randomArray, keyLength: 0, variant: variant) // BAD
let hkdfg1 = HKDF(password: randomArray, salt: randomSalt, info: randomArray, keyLength: 0, variant: variant) // GOOD
// PBKDF1 test cases
let pbkdf1b1 = PKCS5.PBKDF1(password: randomArray, salt: constantSalt, iterations: iterations, keyLength: 0) // $ Alert
let pbkdf1b2 = PKCS5.PBKDF1(password: randomArray, salt: constantStringSalt, iterations: iterations, keyLength: 0) // $ Alert
let pbkdf1b1 = PKCS5.PBKDF1(password: randomArray, salt: constantSalt, iterations: iterations, keyLength: 0) // BAD
let pbkdf1b2 = PKCS5.PBKDF1(password: randomArray, salt: constantStringSalt, iterations: iterations, keyLength: 0) // BAD
let pbkdf1g1 = PKCS5.PBKDF1(password: randomArray, salt: randomSalt, iterations: iterations, keyLength: 0) // GOOD
// PBKDF2 test cases
let pbkdf2b1 = PKCS5.PBKDF2(password: randomArray, salt: constantSalt, iterations: iterations, keyLength: 0) // $ Alert
let pbkdf2b2 = PKCS5.PBKDF2(password: randomArray, salt: constantStringSalt, iterations: iterations, keyLength: 0) // $ Alert
let pbkdf2b1 = PKCS5.PBKDF2(password: randomArray, salt: constantSalt, iterations: iterations, keyLength: 0) // BAD
let pbkdf2b2 = PKCS5.PBKDF2(password: randomArray, salt: constantStringSalt, iterations: iterations, keyLength: 0) // BAD
let pbkdf2g1 = PKCS5.PBKDF2(password: randomArray, salt: randomSalt, iterations: iterations, keyLength: 0) // GOOD
// Scrypt test cases
let scryptb1 = Scrypt(password: randomArray, salt: constantSalt, dkLen: 64, N: 16384, r: 8, p: 1) // $ Alert
let scryptb2 = Scrypt(password: randomArray, salt: constantStringSalt, dkLen: 64, N: 16384, r: 8, p: 1) // $ Alert
let scryptb1 = Scrypt(password: randomArray, salt: constantSalt, dkLen: 64, N: 16384, r: 8, p: 1) // BAD
let scryptb2 = Scrypt(password: randomArray, salt: constantStringSalt, dkLen: 64, N: 16384, r: 8, p: 1) // BAD
let scryptg1 = Scrypt(password: randomArray, salt: randomSalt, dkLen: 64, N: 16384, r: 8, p: 1) // GOOD
}

View File

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

View File

@@ -17,7 +17,7 @@ extension PKCS5 {
}
// Helper functions
func getLowIterationCount() -> Int { return 99999 } // $ Source
func getLowIterationCount() -> Int { return 99999 }
func getEnoughIterationCount() -> Int { return 120120 }
@@ -34,15 +34,15 @@ func test() {
let enoughIterations = getEnoughIterationCount()
// PBKDF1 test cases
let pbkdf1b1 = PKCS5.PBKDF1(password: randomArray, salt: randomArray, iterations: lowIterations, keyLength: 0) // $ Alert
let pbkdf1b2 = PKCS5.PBKDF1(password: randomArray, salt: randomArray, iterations: 80000, keyLength: 0) // $ Alert
let pbkdf1b1 = PKCS5.PBKDF1(password: randomArray, salt: randomArray, iterations: lowIterations, keyLength: 0) // BAD
let pbkdf1b2 = PKCS5.PBKDF1(password: randomArray, salt: randomArray, iterations: 80000, keyLength: 0) // BAD
let pbkdf1g1 = PKCS5.PBKDF1(password: randomArray, salt: randomArray, iterations: enoughIterations, keyLength: 0) // GOOD
let pbkdf1g2 = PKCS5.PBKDF1(password: randomArray, salt: randomArray, iterations: 120120, keyLength: 0) // GOOD
// PBKDF2 test cases
let pbkdf2b1 = PKCS5.PBKDF2(password: randomArray, salt: randomArray, iterations: lowIterations, keyLength: 0) // $ Alert
let pbkdf2b2 = PKCS5.PBKDF2(password: randomArray, salt: randomArray, iterations: 80000, keyLength: 0) // $ Alert
let pbkdf2b1 = PKCS5.PBKDF2(password: randomArray, salt: randomArray, iterations: lowIterations, keyLength: 0) // BAD
let pbkdf2b2 = PKCS5.PBKDF2(password: randomArray, salt: randomArray, iterations: 80000, keyLength: 0) // BAD
let pbkdf2g1 = PKCS5.PBKDF2(password: randomArray, salt: randomArray, iterations: enoughIterations, keyLength: 0) // GOOD
let pbkdf2g2 = PKCS5.PBKDF2(password: randomArray, salt: randomArray, iterations: 120120, keyLength: 0) // GOOD
}