From 5e5e4493044272386751d687632f7b6453cbd74a Mon Sep 17 00:00:00 2001 From: ESS-ENN Date: Tue, 22 Oct 2024 18:41:36 +0530 Subject: [PATCH 1/3] swift-webview-config-allows-universal-file-access-swift --- ...fig-allows-universal-file-access-swift.yml | 198 ++++++++++++++++++ ...s-universal-file-access-swift-snapshot.yml | 72 +++++++ ...llows-universal-file-access-swift-test.yml | 10 + 3 files changed, 280 insertions(+) create mode 100644 rules/swift/security/swift-webview-config-allows-universal-file-access-swift.yml create mode 100644 tests/__snapshots__/swift-webview-config-allows-universal-file-access-swift-snapshot.yml create mode 100644 tests/swift/swift-webview-config-allows-universal-file-access-swift-test.yml diff --git a/rules/swift/security/swift-webview-config-allows-universal-file-access-swift.yml b/rules/swift/security/swift-webview-config-allows-universal-file-access-swift.yml new file mode 100644 index 00000000..acf760d4 --- /dev/null +++ b/rules/swift/security/swift-webview-config-allows-universal-file-access-swift.yml @@ -0,0 +1,198 @@ +id: swift-webview-config-allows-universal-file-access-swift +severity: warning +language: swift +message: >- + Webviews were observed that do not disable access to application files. + If the WebView does not require loading content from the local filesystem + of the application, this setting should be disabled. +note: >- + [CWE-272] Least Privilege Violation. + [REFERENCES] + - https://mas.owasp.org/MASVS/controls/MASVS-PLATFORM-2/ +utils: + match_pattern_two: + kind: call_expression + all: + - has: + stopBy: neighbor + kind: navigation_expression + all: + - has: + stopBy: neighbor + kind: simple_identifier + pattern: $W + - has: + stopBy: neighbor + kind: navigation_suffix + has: + stopBy: neighbor + kind: simple_identifier + regex: "^setValue$" + - has: + stopBy: neighbor + kind: call_suffix + all: + - has: + stopBy: end + kind: value_argument + has: + stopBy: neighbor + kind: boolean_literal + regex: "^true$" + - has: + stopBy: end + kind: value_argument + all: + - has: + stopBy: end + kind: simple_identifier + regex: "^forKey$" + - has: + stopBy: neighbor + kind: line_string_literal + has: + stopBy: neighbor + kind: line_str_text + regex: "^allowUniversalAccessFromFileURLs$" + - follows: + stopBy: end + kind: property_declaration + all: + - has: + stopBy: end + kind: pattern + has: + stopBy: neighbor + kind: simple_identifier + pattern: $W + - any: + - has: + stopBy: neighbor + kind: navigation_expression + - has: + stopBy: neighbor + kind: call_expression + - not: + precedes: + stopBy: neighbor + kind: call_expression + all: + - has: + stopBy: neighbor + kind: navigation_expression + all: + - has: + stopBy: neighbor + kind: simple_identifier + pattern: $W + - has: + stopBy: neighbor + kind: navigation_suffix + has: + stopBy: neighbor + kind: simple_identifier + regex: "^setValue$" + - has: + stopBy: neighbor + kind: call_suffix + all: + - has: + stopBy: end + kind: value_argument + has: + stopBy: neighbor + kind: boolean_literal + regex: "^false$" + - has: + stopBy: end + kind: value_argument + all: + - has: + stopBy: end + kind: simple_identifier + regex: "^forKey$" + - has: + stopBy: neighbor + kind: line_string_literal + has: + stopBy: neighbor + kind: line_str_text + regex: "^allowUniversalAccessFromFileURLs$" + + match_pattern_one: + kind: call_expression + all: + - has: + stopBy: neighbor + kind: navigation_expression + all: + - has: + stopBy: neighbor + kind: navigation_expression + all: + - has: + stopBy: end + kind: simple_identifier + pattern: $L + - has: + stopBy: neighbor + kind: navigation_suffix + has: + stopBy: neighbor + kind: simple_identifier + regex: "^configuration$" + - has: + stopBy: neighbor + kind: navigation_suffix + has: + stopBy: neighbor + kind: simple_identifier + regex: "^setValue$" + - has: + stopBy: neighbor + kind: call_suffix + has: + stopBy: neighbor + kind: value_arguments + all: + - has: + stopBy: neighbor + kind: value_argument + has: + stopBy: neighbor + kind: boolean_literal + regex: "^true$" + - has: + stopBy: neighbor + kind: value_argument + all: + - has: + stopBy: neighbor + kind: simple_identifier + regex: "^forKey$" + - has: + stopBy: neighbor + kind: line_string_literal + has: + stopBy: neighbor + kind: line_str_text + regex: "^allowUniversalAccessFromFileURLs$" + - follows: + stopBy: neighbor + kind: property_declaration + all: + - has: + stopBy: end + kind: pattern + has: + stopBy: neighbor + kind: simple_identifier + pattern: $L + - has: + stopBy: neighbor + kind: call_expression +rule: + kind: call_expression + any: + - matches: match_pattern_two + - matches: match_pattern_one diff --git a/tests/__snapshots__/swift-webview-config-allows-universal-file-access-swift-snapshot.yml b/tests/__snapshots__/swift-webview-config-allows-universal-file-access-swift-snapshot.yml new file mode 100644 index 00000000..d9b88f84 --- /dev/null +++ b/tests/__snapshots__/swift-webview-config-allows-universal-file-access-swift-snapshot.yml @@ -0,0 +1,72 @@ +id: swift-webview-config-allows-universal-file-access-swift +snapshots: + ? | + let w = WKWebView(frame: .zero, configuration: config) + w.setValue(true, forKey: "allowUniversalAccessFromFileURLs") + let config = w.configuration + config.setValue(true, forKey: "allowUniversalAccessFromFileURLs") + : labels: + - source: 'w.setValue(true, forKey: "allowUniversalAccessFromFileURLs")' + style: primary + start: 55 + end: 115 + - source: w + style: secondary + start: 55 + end: 56 + - source: setValue + style: secondary + start: 57 + end: 65 + - source: .setValue + style: secondary + start: 56 + end: 65 + - source: w.setValue + style: secondary + start: 55 + end: 65 + - source: 'true' + style: secondary + start: 66 + end: 70 + - source: 'true' + style: secondary + start: 66 + end: 70 + - source: forKey + style: secondary + start: 72 + end: 78 + - source: allowUniversalAccessFromFileURLs + style: secondary + start: 81 + end: 113 + - source: '"allowUniversalAccessFromFileURLs"' + style: secondary + start: 80 + end: 114 + - source: 'forKey: "allowUniversalAccessFromFileURLs"' + style: secondary + start: 72 + end: 114 + - source: '(true, forKey: "allowUniversalAccessFromFileURLs")' + style: secondary + start: 65 + end: 115 + - source: w + style: secondary + start: 4 + end: 5 + - source: w + style: secondary + start: 4 + end: 5 + - source: 'WKWebView(frame: .zero, configuration: config)' + style: secondary + start: 8 + end: 54 + - source: 'let w = WKWebView(frame: .zero, configuration: config)' + style: secondary + start: 0 + end: 54 diff --git a/tests/swift/swift-webview-config-allows-universal-file-access-swift-test.yml b/tests/swift/swift-webview-config-allows-universal-file-access-swift-test.yml new file mode 100644 index 00000000..decafaf1 --- /dev/null +++ b/tests/swift/swift-webview-config-allows-universal-file-access-swift-test.yml @@ -0,0 +1,10 @@ +id: swift-webview-config-allows-universal-file-access-swift +valid: + - | + +invalid: + - | + let w = WKWebView(frame: .zero, configuration: config) + w.setValue(true, forKey: "allowUniversalAccessFromFileURLs") + let config = w.configuration + config.setValue(true, forKey: "allowUniversalAccessFromFileURLs") From dffb60c1dbb0a072ba65aa93c1ce29cfd1e48123 Mon Sep 17 00:00:00 2001 From: ESS-ENN Date: Tue, 22 Oct 2024 18:42:37 +0530 Subject: [PATCH 2/3] swift-webview-config-https-upgrade-swift --- ...ift-webview-config-https-upgrade-swift.yml | 113 ++++++++++++++++++ ...ew-config-https-upgrade-swift-snapshot.yml | 48 ++++++++ ...ebview-config-https-upgrade-swift-test.yml | 16 +++ 3 files changed, 177 insertions(+) create mode 100644 rules/swift/security/swift-webview-config-https-upgrade-swift.yml create mode 100644 tests/__snapshots__/swift-webview-config-https-upgrade-swift-snapshot.yml create mode 100644 tests/swift/swift-webview-config-https-upgrade-swift-test.yml diff --git a/rules/swift/security/swift-webview-config-https-upgrade-swift.yml b/rules/swift/security/swift-webview-config-https-upgrade-swift.yml new file mode 100644 index 00000000..726479f8 --- /dev/null +++ b/rules/swift/security/swift-webview-config-https-upgrade-swift.yml @@ -0,0 +1,113 @@ +id: swift-webview-config-https-upgrade-swift +severity: warning +language: swift +message: >- + Webviews were observed that do not enable the + `upgradeKnownHostsToHTTPS` feature. This feature will ensure accidental + HTTP connections are automatically upgraded to HTTPS, avoiding potential + data leakage over the network. +note: >- + [CWE-272] Least Privilege Violation. + [REFERENCES] + - https://developer.apple.com/documentation/webkit/wkwebviewconfiguration/3752243-upgradeknownhoststohttps + - https://mas.owasp.org/MASVS/controls/MASVS-PLATFORM-2/ +utils: + match_pattern_upgradeKnownHostsToHTTPS: + kind: assignment + all: + - has: + stopBy: neighbor + kind: directly_assignable_expression + all: + - has: + stopBy: end + kind: simple_identifier + pattern: $F + - has: + stopBy: end + kind: navigation_suffix + has: + stopBy: neighbor + kind: simple_identifier + regex: "^upgradeKnownHostsToHTTPS$" + - has: + stopBy: neighbor + regex: "^=$" + - has: + stopBy: neighbor + kind: boolean_literal + regex: "^false$" + - follows: + stopBy: end + kind: property_declaration + all: + - has: + stopBy: end + kind: pattern + has: + stopBy: neighbor + kind: simple_identifier + pattern: $F + - has: + stopBy: neighbor + kind: call_expression + pattern: WKWebViewConfiguration() + - not: + follows: + stopBy: end + kind: assignment + all: + - has: + stopBy: neighbor + kind: directly_assignable_expression + all: + - has: + stopBy: end + kind: simple_identifier + pattern: $F + - has: + stopBy: end + kind: navigation_suffix + has: + stopBy: neighbor + kind: simple_identifier + regex: "^upgradeKnownHostsToHTTPS$" + - has: + stopBy: neighbor + regex: "^=$" + - has: + stopBy: neighbor + kind: boolean_literal + regex: "^false$" + - not: + precedes: + stopBy: neighbor + kind: assignment + all: + - all: + - has: + stopBy: neighbor + kind: directly_assignable_expression + all: + - has: + stopBy: end + kind: simple_identifier + pattern: $F + - has: + stopBy: end + kind: navigation_suffix + has: + stopBy: neighbor + kind: simple_identifier + regex: "^upgradeKnownHostsToHTTPS$" + - has: + stopBy: neighbor + regex: "^=$" + - has: + stopBy: neighbor + kind: boolean_literal + regex: "^false$" + +rule: + kind: assignment + matches: match_pattern_upgradeKnownHostsToHTTPS diff --git a/tests/__snapshots__/swift-webview-config-https-upgrade-swift-snapshot.yml b/tests/__snapshots__/swift-webview-config-https-upgrade-swift-snapshot.yml new file mode 100644 index 00000000..e7cd7081 --- /dev/null +++ b/tests/__snapshots__/swift-webview-config-https-upgrade-swift-snapshot.yml @@ -0,0 +1,48 @@ +id: swift-webview-config-https-upgrade-swift +snapshots: + ? "let prefs2 = WKPreferences()\nlet config2 = WKWebViewConfiguration()\nconfig2.upgradeKnownHostsToHTTPS = true\nconfig2.upgradeKnownHostsToHTTPS = false\nconfig.defaultWebpagePreferences = prefs2 \nWKWebView(frame: .zero, configuration: config)\n" + : labels: + - source: config2.upgradeKnownHostsToHTTPS = false + style: primary + start: 109 + end: 150 + - source: config2 + style: secondary + start: 109 + end: 116 + - source: upgradeKnownHostsToHTTPS + style: secondary + start: 117 + end: 141 + - source: .upgradeKnownHostsToHTTPS + style: secondary + start: 116 + end: 141 + - source: config2.upgradeKnownHostsToHTTPS + style: secondary + start: 109 + end: 141 + - source: = + style: secondary + start: 143 + end: 144 + - source: 'false' + style: secondary + start: 145 + end: 150 + - source: config2 + style: secondary + start: 33 + end: 40 + - source: config2 + style: secondary + start: 33 + end: 40 + - source: WKWebViewConfiguration() + style: secondary + start: 43 + end: 67 + - source: let config2 = WKWebViewConfiguration() + style: secondary + start: 29 + end: 67 diff --git a/tests/swift/swift-webview-config-https-upgrade-swift-test.yml b/tests/swift/swift-webview-config-https-upgrade-swift-test.yml new file mode 100644 index 00000000..0e25efe3 --- /dev/null +++ b/tests/swift/swift-webview-config-https-upgrade-swift-test.yml @@ -0,0 +1,16 @@ +id: swift-webview-config-https-upgrade-swift +valid: + - | + let prefs = WKPreferences() + let config = WKWebViewConfiguration() + config.upgradeKnownHostsToHTTPS = true + config.defaultWebpagePreferences = prefs + WKWebView(frame: .zero, configuration: config) +invalid: + - | + let prefs2 = WKPreferences() + let config2 = WKWebViewConfiguration() + config2.upgradeKnownHostsToHTTPS = true + config2.upgradeKnownHostsToHTTPS = false + config.defaultWebpagePreferences = prefs2 + WKWebView(frame: .zero, configuration: config) From 6fafd66d2f482e94d46e594a0521f45c49fd7468 Mon Sep 17 00:00:00 2001 From: ESS-ENN Date: Thu, 24 Oct 2024 17:55:36 +0530 Subject: [PATCH 3/3] changes in swift-webview-config-allows-universal-file-access-swift --- ...-webview-config-allows-universal-file-access-swift-test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/swift/swift-webview-config-allows-universal-file-access-swift-test.yml b/tests/swift/swift-webview-config-allows-universal-file-access-swift-test.yml index decafaf1..a10c40cb 100644 --- a/tests/swift/swift-webview-config-allows-universal-file-access-swift-test.yml +++ b/tests/swift/swift-webview-config-allows-universal-file-access-swift-test.yml @@ -1,7 +1,8 @@ id: swift-webview-config-allows-universal-file-access-swift valid: - | - + let w2 = WKWebView(frame: .zero, configuration: config) + w2.configuration.setValue(false, forKey: "allowUniversalAccessFromFileURLs") invalid: - | let w = WKWebView(frame: .zero, configuration: config)