From 1850da920928de954f7c88803aca038b42c143f1 Mon Sep 17 00:00:00 2001 From: ESS-ENN Date: Fri, 6 Dec 2024 16:55:00 +0530 Subject: [PATCH 1/3] swift-webview-config-allows-file-access-swift --- ...ebview-config-allows-file-access-swift.yml | 57 +++++++++ ...nfig-allows-file-access-swift-snapshot.yml | 117 ++++++++++++++++++ ...w-config-allows-file-access-swift-test.yml | 15 +++ 3 files changed, 189 insertions(+) create mode 100644 rules/swift/security/swift-webview-config-allows-file-access-swift.yml create mode 100644 tests/__snapshots__/swift-webview-config-allows-file-access-swift-snapshot.yml create mode 100644 tests/swift/swift-webview-config-allows-file-access-swift-test.yml diff --git a/rules/swift/security/swift-webview-config-allows-file-access-swift.yml b/rules/swift/security/swift-webview-config-allows-file-access-swift.yml new file mode 100644 index 00000000..1da9384e --- /dev/null +++ b/rules/swift/security/swift-webview-config-allows-file-access-swift.yml @@ -0,0 +1,57 @@ +id: swift-webview-config-allows-file-access-swift +language: swift +severity: warning +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_call_expression: + kind: call_expression + has: + stopBy: end + kind: call_suffix + has: + stopBy: end + kind: value_arguments + all: + - has: + stopBy: end + kind: value_argument + has: + stopBy: end + kind: boolean_literal + field: value + regex: '^true$' + - has: + stopBy: end + kind: value_argument + all: + - has: + stopBy: end + kind: simple_identifier + regex: '^forKey$' + - has: + stopBy: end + kind: line_string_literal + has: + stopBy: end + kind: line_str_text + regex: '^allowFileAccessFromFileURLs$' + + +rule: + any: + - matches: match_call_expression + + + + + + + + diff --git a/tests/__snapshots__/swift-webview-config-allows-file-access-swift-snapshot.yml b/tests/__snapshots__/swift-webview-config-allows-file-access-swift-snapshot.yml new file mode 100644 index 00000000..afd624f0 --- /dev/null +++ b/tests/__snapshots__/swift-webview-config-allows-file-access-swift-snapshot.yml @@ -0,0 +1,117 @@ +id: swift-webview-config-allows-file-access-swift +snapshots: + ? "func enableFileAccessFromFileURLs() {\nwebView.configuration.preferences.setValue(true, forKey: \"allowFileAccessFromFileURLs\")\nprint(\"allowFileAccessFromFileURLs has been set to true.\")\n} \n" + : labels: + - source: 'webView.configuration.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")' + style: primary + start: 38 + end: 125 + - source: 'true' + style: secondary + start: 81 + end: 85 + - source: 'true' + style: secondary + start: 81 + end: 85 + - source: forKey + style: secondary + start: 87 + end: 93 + - source: allowFileAccessFromFileURLs + style: secondary + start: 96 + end: 123 + - source: '"allowFileAccessFromFileURLs"' + style: secondary + start: 95 + end: 124 + - source: 'forKey: "allowFileAccessFromFileURLs"' + style: secondary + start: 87 + end: 124 + - source: '(true, forKey: "allowFileAccessFromFileURLs")' + style: secondary + start: 80 + end: 125 + - source: '(true, forKey: "allowFileAccessFromFileURLs")' + style: secondary + start: 80 + end: 125 + ? | + preferences.setValue(true, forKey: "allowFileAccessFromFileURLs") + : labels: + - source: 'preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")' + style: primary + start: 0 + end: 65 + - source: 'true' + style: secondary + start: 21 + end: 25 + - source: 'true' + style: secondary + start: 21 + end: 25 + - source: forKey + style: secondary + start: 27 + end: 33 + - source: allowFileAccessFromFileURLs + style: secondary + start: 36 + end: 63 + - source: '"allowFileAccessFromFileURLs"' + style: secondary + start: 35 + end: 64 + - source: 'forKey: "allowFileAccessFromFileURLs"' + style: secondary + start: 27 + end: 64 + - source: '(true, forKey: "allowFileAccessFromFileURLs")' + style: secondary + start: 20 + end: 65 + - source: '(true, forKey: "allowFileAccessFromFileURLs")' + style: secondary + start: 20 + end: 65 + ? "webViewConfig.webView.configuration.preferences.setValue(true, forKey: \"allowFileAccessFromFileURLs\") \n" + : labels: + - source: 'webViewConfig.webView.configuration.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")' + style: primary + start: 0 + end: 101 + - source: 'true' + style: secondary + start: 57 + end: 61 + - source: 'true' + style: secondary + start: 57 + end: 61 + - source: forKey + style: secondary + start: 63 + end: 69 + - source: allowFileAccessFromFileURLs + style: secondary + start: 72 + end: 99 + - source: '"allowFileAccessFromFileURLs"' + style: secondary + start: 71 + end: 100 + - source: 'forKey: "allowFileAccessFromFileURLs"' + style: secondary + start: 63 + end: 100 + - source: '(true, forKey: "allowFileAccessFromFileURLs")' + style: secondary + start: 56 + end: 101 + - source: '(true, forKey: "allowFileAccessFromFileURLs")' + style: secondary + start: 56 + end: 101 diff --git a/tests/swift/swift-webview-config-allows-file-access-swift-test.yml b/tests/swift/swift-webview-config-allows-file-access-swift-test.yml new file mode 100644 index 00000000..c69a18d6 --- /dev/null +++ b/tests/swift/swift-webview-config-allows-file-access-swift-test.yml @@ -0,0 +1,15 @@ +id: swift-webview-config-allows-file-access-swift +valid: + - | + +invalid: + - | + preferences.setValue(true, forKey: "allowFileAccessFromFileURLs") + - | + func enableFileAccessFromFileURLs() { + webView.configuration.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs") + print("allowFileAccessFromFileURLs has been set to true.") + } + - | + webViewConfig.webView.configuration.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs") + From 6f2512cc81cbb1574c7dd9a6cb963cc77c5bf3e3 Mon Sep 17 00:00:00 2001 From: ESS-ENN Date: Fri, 6 Dec 2024 17:00:06 +0530 Subject: [PATCH 2/3] swift-webview-config-fraudulent-site-warning-swift --- ...w-config-fraudulent-site-warning-swift.yml | 100 ++++++++++++++++++ ...fraudulent-site-warning-swift-snapshot.yml | 81 ++++++++++++++ ...fig-fraudulent-site-warning-swift-test.yml | 14 +++ 3 files changed, 195 insertions(+) create mode 100644 rules/swift/security/swift-webview-config-fraudulent-site-warning-swift.yml create mode 100644 tests/__snapshots__/swift-webview-config-fraudulent-site-warning-swift-snapshot.yml create mode 100644 tests/swift/swift-webview-config-fraudulent-site-warning-swift-test.yml diff --git a/rules/swift/security/swift-webview-config-fraudulent-site-warning-swift.yml b/rules/swift/security/swift-webview-config-fraudulent-site-warning-swift.yml new file mode 100644 index 00000000..eabda44f --- /dev/null +++ b/rules/swift/security/swift-webview-config-fraudulent-site-warning-swift.yml @@ -0,0 +1,100 @@ +id: swift-webview-config-fraudulent-site-warning-swift +language: swift +severity: warning +message: >- + Webviews were observed that explicitly opt ouf of the WKWebView + fraudulent site warnings. Consider enabling such functionality, to better + protect your users from fraud/malware. +note: >- + [CWE-272]: Least Privilege Violation + [REFERENCES] + https://mas.owasp.org/MASVS/controls/MASVS-PLATFORM-2/ +utils: + match_isFraudulentWebsiteWarningEnabled: + kind: assignment + all: + - has: + stopBy: end + kind: navigation_expression + has: + stopBy: end + kind: simple_identifier + pattern: $R + - has: + stopBy: end + kind: navigation_suffix + has: + stopBy: end + kind: simple_identifier + regex: "^isFraudulentWebsiteWarningEnabled$" + - has: + kind: boolean_literal + regex: "^false$" + - follows: + stopBy: end + kind: property_declaration + has: + stopBy: end + kind: pattern + has: + kind: simple_identifier + pattern: $R + - not: + precedes: + kind: assignment + has: + kind: boolean_literal + regex: "false$|true" + - not: + follows: + kind: assignment + has: + stopBy: end + kind: boolean_literal + regex: "^false" + match_simple_identifier: + kind: assignment + all: + - has: + stopBy: end + kind: navigation_expression + has: + stopBy: end + kind: simple_identifier + pattern: $R + - has: + stopBy: end + kind: navigation_suffix + has: + stopBy: end + kind: simple_identifier + regex: "^isFraudulentWebsiteWarningEnabled$" + - has: + kind: simple_identifier + - follows: + stopBy: end + kind: property_declaration + has: + stopBy: end + kind: pattern + has: + kind: simple_identifier + pattern: $R + - not: + precedes: + kind: assignment + has: + kind: boolean_literal + regex: "false$|true" + - not: + follows: + kind: assignment + has: + stopBy: end + kind: boolean_literal + regex: "^false" + +rule: + any: + - matches: match_isFraudulentWebsiteWarningEnabled + - matches: match_simple_identifier diff --git a/tests/__snapshots__/swift-webview-config-fraudulent-site-warning-swift-snapshot.yml b/tests/__snapshots__/swift-webview-config-fraudulent-site-warning-swift-snapshot.yml new file mode 100644 index 00000000..d725f1da --- /dev/null +++ b/tests/__snapshots__/swift-webview-config-fraudulent-site-warning-swift-snapshot.yml @@ -0,0 +1,81 @@ +id: swift-webview-config-fraudulent-site-warning-swift +snapshots: + ? "let prefs2 = WKPreferences()\nprefs2.isFraudulentWebsiteWarningEnabled = false \n" + : labels: + - source: prefs2.isFraudulentWebsiteWarningEnabled = false + style: primary + start: 29 + end: 78 + - source: prefs2 + style: secondary + start: 29 + end: 35 + - source: prefs2.isFraudulentWebsiteWarningEnabled + style: secondary + start: 29 + end: 69 + - source: isFraudulentWebsiteWarningEnabled + style: secondary + start: 36 + end: 69 + - source: .isFraudulentWebsiteWarningEnabled + style: secondary + start: 35 + end: 69 + - source: 'false' + style: secondary + start: 73 + end: 78 + - source: prefs2 + style: secondary + start: 4 + end: 10 + - source: prefs2 + style: secondary + start: 4 + end: 10 + - source: let prefs2 = WKPreferences() + style: secondary + start: 0 + end: 28 + ? | + let prefs2 = WKPreferences() + prefs2.isFraudulentWebsiteWarningEnabled = true + prefs2.isFraudulentWebsiteWarningEnabled = false + : labels: + - source: prefs2.isFraudulentWebsiteWarningEnabled = false + style: primary + start: 78 + end: 127 + - source: prefs2 + style: secondary + start: 78 + end: 84 + - source: prefs2.isFraudulentWebsiteWarningEnabled + style: secondary + start: 78 + end: 118 + - source: isFraudulentWebsiteWarningEnabled + style: secondary + start: 85 + end: 118 + - source: .isFraudulentWebsiteWarningEnabled + style: secondary + start: 84 + end: 118 + - source: 'false' + style: secondary + start: 122 + end: 127 + - source: prefs2 + style: secondary + start: 4 + end: 10 + - source: prefs2 + style: secondary + start: 4 + end: 10 + - source: let prefs2 = WKPreferences() + style: secondary + start: 0 + end: 28 diff --git a/tests/swift/swift-webview-config-fraudulent-site-warning-swift-test.yml b/tests/swift/swift-webview-config-fraudulent-site-warning-swift-test.yml new file mode 100644 index 00000000..c390f316 --- /dev/null +++ b/tests/swift/swift-webview-config-fraudulent-site-warning-swift-test.yml @@ -0,0 +1,14 @@ +id: swift-webview-config-fraudulent-site-warning-swift +valid: + - | + let prefs = WKPreferences() + prefs.isFraudulentWebsiteWarningEnabled = true +invalid: + - | + let prefs2 = WKPreferences() + prefs2.isFraudulentWebsiteWarningEnabled = true + prefs2.isFraudulentWebsiteWarningEnabled = false + - | + let prefs2 = WKPreferences() + prefs2.isFraudulentWebsiteWarningEnabled = false + From 7e72fd3c0e3920b19205f736696253111f737ff5 Mon Sep 17 00:00:00 2001 From: ESS-ENN Date: Fri, 6 Dec 2024 17:01:29 +0530 Subject: [PATCH 3/3] swift-webview-config-https-upgrade-swift --- ...ift-webview-config-https-upgrade-swift.yml | 115 ++++++++++ ...ew-config-https-upgrade-swift-snapshot.yml | 204 ++++++++++++++++++ ...ebview-config-https-upgrade-swift-test.yml | 37 ++++ 3 files changed, 356 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..8247a17f --- /dev/null +++ b/rules/swift/security/swift-webview-config-https-upgrade-swift.yml @@ -0,0 +1,115 @@ +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: end + 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 + +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..e87e5936 --- /dev/null +++ b/tests/__snapshots__/swift-webview-config-https-upgrade-swift-snapshot.yml @@ -0,0 +1,204 @@ +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 + ? | + let prefs2 = WKPreferences() + let config2 = WKWebViewConfiguration() + config2.upgradeKnownHostsToHTTPS = false + config2.defaultWebpagePreferences = prefs2 + let webView2 = WKWebView(frame: .zero, configuration: config2) + self.view.addSubview(webView2) + : labels: + - source: config2.upgradeKnownHostsToHTTPS = false + style: primary + start: 68 + end: 108 + - source: config2 + style: secondary + start: 68 + end: 75 + - source: upgradeKnownHostsToHTTPS + style: secondary + start: 76 + end: 100 + - source: .upgradeKnownHostsToHTTPS + style: secondary + start: 75 + end: 100 + - source: config2.upgradeKnownHostsToHTTPS + style: secondary + start: 68 + end: 100 + - source: = + style: secondary + start: 101 + end: 102 + - source: 'false' + style: secondary + start: 103 + end: 108 + - 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 + ? | + let prefs5 = WKPreferences() + let config5 = WKWebViewConfiguration() + config5.upgradeKnownHostsToHTTPS = false + config5.defaultWebpagePreferences = prefs5 + let webView5 = WKWebView(frame: .zero, configuration: config5) + self.view.addSubview(webView5) + : labels: + - source: config5.upgradeKnownHostsToHTTPS = false + style: primary + start: 68 + end: 108 + - source: config5 + style: secondary + start: 68 + end: 75 + - source: upgradeKnownHostsToHTTPS + style: secondary + start: 76 + end: 100 + - source: .upgradeKnownHostsToHTTPS + style: secondary + start: 75 + end: 100 + - source: config5.upgradeKnownHostsToHTTPS + style: secondary + start: 68 + end: 100 + - source: = + style: secondary + start: 101 + end: 102 + - source: 'false' + style: secondary + start: 103 + end: 108 + - source: config5 + style: secondary + start: 33 + end: 40 + - source: config5 + style: secondary + start: 33 + end: 40 + - source: WKWebViewConfiguration() + style: secondary + start: 43 + end: 67 + - source: let config5 = WKWebViewConfiguration() + style: secondary + start: 29 + end: 67 + ? | + let prefs7 = WKPreferences() + let config7 = WKWebViewConfiguration() + config7.upgradeKnownHostsToHTTPS = false + config7.defaultWebpagePreferences = prefs7 + let webView7 = WKWebView(frame: .zero, configuration: config7) + self.view.addSubview(webView7) + : labels: + - source: config7.upgradeKnownHostsToHTTPS = false + style: primary + start: 68 + end: 108 + - source: config7 + style: secondary + start: 68 + end: 75 + - source: upgradeKnownHostsToHTTPS + style: secondary + start: 76 + end: 100 + - source: .upgradeKnownHostsToHTTPS + style: secondary + start: 75 + end: 100 + - source: config7.upgradeKnownHostsToHTTPS + style: secondary + start: 68 + end: 100 + - source: = + style: secondary + start: 101 + end: 102 + - source: 'false' + style: secondary + start: 103 + end: 108 + - source: config7 + style: secondary + start: 33 + end: 40 + - source: config7 + style: secondary + start: 33 + end: 40 + - source: WKWebViewConfiguration() + style: secondary + start: 43 + end: 67 + - source: let config7 = 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..d9924b57 --- /dev/null +++ b/tests/swift/swift-webview-config-https-upgrade-swift-test.yml @@ -0,0 +1,37 @@ +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) + - | + let prefs7 = WKPreferences() + let config7 = WKWebViewConfiguration() + config7.upgradeKnownHostsToHTTPS = false + config7.defaultWebpagePreferences = prefs7 + let webView7 = WKWebView(frame: .zero, configuration: config7) + self.view.addSubview(webView7) + - | + let prefs5 = WKPreferences() + let config5 = WKWebViewConfiguration() + config5.upgradeKnownHostsToHTTPS = false + config5.defaultWebpagePreferences = prefs5 + let webView5 = WKWebView(frame: .zero, configuration: config5) + self.view.addSubview(webView5) + - | + let prefs2 = WKPreferences() + let config2 = WKWebViewConfiguration() + config2.upgradeKnownHostsToHTTPS = false + config2.defaultWebpagePreferences = prefs2 + let webView2 = WKWebView(frame: .zero, configuration: config2) + self.view.addSubview(webView2)