diff --git a/rules/swift/security/swift-webview-config-allows-js-swift.yml b/rules/swift/security/swift-webview-config-allows-js-swift.yml new file mode 100644 index 0000000..f99f095 --- /dev/null +++ b/rules/swift/security/swift-webview-config-allows-js-swift.yml @@ -0,0 +1,110 @@ +id: swift-webview-config-allows-js-swift +severity: warning +language: swift +message: >- + Webviews were observed that do not have JavaScript disabled. Consider + disabling JavaScript wherever the functionality is not required, following + the principle of least privelege. +note: >- + [CWE-272] Least Privilege Violation. + [REFERENCES] + - 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: "^javaScriptEnabled|allowsContentJavaScript$" + - has: + stopBy: neighbor + regex: "^=$" + - has: + stopBy: neighbor + kind: boolean_literal + regex: "^true$" + - 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 + any: + - pattern: WKWebpagePreferences() + - pattern: WKPreferences() + - 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: "^(javaScriptEnabled|allowsContentJavaScript)$" + - has: + stopBy: neighbor + regex: "^=$" + - has: + stopBy: neighbor + kind: boolean_literal + regex: "^true$" + - not: + precedes: + 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: "^(javaScriptEnabled|allowsContentJavaScript)$" + - has: + stopBy: neighbor + regex: "^=$" + - has: + stopBy: neighbor + pattern: $$$ +rule: + kind: assignment + matches: match_pattern_upgradeKnownHostsToHTTPS diff --git a/rules/swift/security/swift-webview-config-base-url-swift.yml b/rules/swift/security/swift-webview-config-base-url-swift.yml new file mode 100644 index 0000000..09bb5d8 --- /dev/null +++ b/rules/swift/security/swift-webview-config-base-url-swift.yml @@ -0,0 +1,65 @@ +id: swift-webview-config-base-url-swift +severity: warning +language: swift +message: >- + UIWebView instances were observed where the baseURL is misconfigured as + nil, which allows for origin abuse within the webview. In order to remove + the effective origin, the application should explicitly set the baseURL to + `about:blank` or similar. +note: >- + [CWE-272] Least Privilege Violation. + [REFERENCES] + - https://mas.owasp.org/MASVS/controls/MASVS-PLATFORM-2/ +utils: + matches_patttern_loadHTMLString_&_load: + kind: call_expression + all: + - has: + stopBy: end + kind: navigation_expression + all: + - has: + stopBy: end + kind: simple_identifier + pattern: $W + - has: + stopBy: end + kind: navigation_suffix + has: + stopBy: end + kind: simple_identifier + regex: "^loadHTMLString|load$" + - has: + stopBy: end + kind: call_suffix + has: + stopBy: end + kind: value_argument + all: + - has: + stopBy: end + kind: simple_identifier + regex: "^baseURL$" + - has: + stopBy: end + regex: "^nil$" + - follows: + stopBy: end + kind: property_declaration + all: + - all: + - has: + stopBy: end + kind: pattern + has: + stopBy: end + kind: simple_identifier + pattern: $W + - has: + stopBy: end + kind: call_expression + pattern: UIWebView(...) + +rule: + kind: call_expression + matches: matches_patttern_loadHTMLString_&_load diff --git a/tests/__snapshots__/swift-webview-config-allows-js-swift-snapshot.yml b/tests/__snapshots__/swift-webview-config-allows-js-swift-snapshot.yml new file mode 100644 index 0000000..45696ab --- /dev/null +++ b/tests/__snapshots__/swift-webview-config-allows-js-swift-snapshot.yml @@ -0,0 +1,101 @@ +id: swift-webview-config-allows-js-swift +snapshots: + ? | + let preferences = WKPreferences() + preferences.javaScriptEnabled = true + preferences.javaScriptCanOpenWindowsAutomatically = false + : labels: + - source: preferences.javaScriptEnabled = true + style: primary + start: 34 + end: 70 + - source: preferences + style: secondary + start: 34 + end: 45 + - source: javaScriptEnabled + style: secondary + start: 46 + end: 63 + - source: .javaScriptEnabled + style: secondary + start: 45 + end: 63 + - source: preferences.javaScriptEnabled + style: secondary + start: 34 + end: 63 + - source: = + style: secondary + start: 64 + end: 65 + - source: 'true' + style: secondary + start: 66 + end: 70 + - source: preferences + style: secondary + start: 4 + end: 15 + - source: preferences + style: secondary + start: 4 + end: 15 + - source: WKPreferences() + style: secondary + start: 18 + end: 33 + - source: let preferences = WKPreferences() + style: secondary + start: 0 + end: 33 + ? | + let prefs = WKWebpagePreferences() + prefs.allowsContentJavaScript = true + let config = WKWebViewConfiguration() + config.defaultWebpagePreferences = prefs + : labels: + - source: prefs.allowsContentJavaScript = true + style: primary + start: 35 + end: 71 + - source: prefs + style: secondary + start: 35 + end: 40 + - source: allowsContentJavaScript + style: secondary + start: 41 + end: 64 + - source: .allowsContentJavaScript + style: secondary + start: 40 + end: 64 + - source: prefs.allowsContentJavaScript + style: secondary + start: 35 + end: 64 + - source: = + style: secondary + start: 65 + end: 66 + - source: 'true' + style: secondary + start: 67 + end: 71 + - source: prefs + style: secondary + start: 4 + end: 9 + - source: prefs + style: secondary + start: 4 + end: 9 + - source: WKWebpagePreferences() + style: secondary + start: 12 + end: 34 + - source: let prefs = WKWebpagePreferences() + style: secondary + start: 0 + end: 34 diff --git a/tests/__snapshots__/swift-webview-config-base-url-swift-snapshot.yml b/tests/__snapshots__/swift-webview-config-base-url-swift-snapshot.yml new file mode 100644 index 0000000..a6024a4 --- /dev/null +++ b/tests/__snapshots__/swift-webview-config-base-url-swift-snapshot.yml @@ -0,0 +1,114 @@ +id: swift-webview-config-base-url-swift +snapshots: + ? | + let webview = UIWebView(...) + webview.loadHTMLString(someHtmlString, baseURL: nil) + : labels: + - source: 'webview.loadHTMLString(someHtmlString, baseURL: nil)' + style: primary + start: 29 + end: 81 + - source: webview + style: secondary + start: 29 + end: 36 + - source: loadHTMLString + style: secondary + start: 37 + end: 51 + - source: .loadHTMLString + style: secondary + start: 36 + end: 51 + - source: webview.loadHTMLString + style: secondary + start: 29 + end: 51 + - source: baseURL + style: secondary + start: 68 + end: 75 + - source: nil + style: secondary + start: 77 + end: 80 + - source: 'baseURL: nil' + style: secondary + start: 68 + end: 80 + - source: '(someHtmlString, baseURL: nil)' + style: secondary + start: 51 + end: 81 + - source: webview + style: secondary + start: 4 + end: 11 + - source: webview + style: secondary + start: 4 + end: 11 + - source: UIWebView(...) + style: secondary + start: 14 + end: 28 + - source: let webview = UIWebView(...) + style: secondary + start: 0 + end: 28 + ? | + let webview3 = UIWebView(...) + webview3.load(data, mimetype: "application/json", textEncodingName: "UTF8", baseURL: nil) + : labels: + - source: 'webview3.load(data, mimetype: "application/json", textEncodingName: "UTF8", baseURL: nil)' + style: primary + start: 30 + end: 119 + - source: webview3 + style: secondary + start: 30 + end: 38 + - source: load + style: secondary + start: 39 + end: 43 + - source: .load + style: secondary + start: 38 + end: 43 + - source: webview3.load + style: secondary + start: 30 + end: 43 + - source: baseURL + style: secondary + start: 106 + end: 113 + - source: nil + style: secondary + start: 115 + end: 118 + - source: 'baseURL: nil' + style: secondary + start: 106 + end: 118 + - source: '(data, mimetype: "application/json", textEncodingName: "UTF8", baseURL: nil)' + style: secondary + start: 43 + end: 119 + - source: webview3 + style: secondary + start: 4 + end: 12 + - source: webview3 + style: secondary + start: 4 + end: 12 + - source: UIWebView(...) + style: secondary + start: 15 + end: 29 + - source: let webview3 = UIWebView(...) + style: secondary + start: 0 + end: 29 diff --git a/tests/swift/swift-webview-config-allows-js-swift-test.yml b/tests/swift/swift-webview-config-allows-js-swift-test.yml new file mode 100644 index 0000000..17939d0 --- /dev/null +++ b/tests/swift/swift-webview-config-allows-js-swift-test.yml @@ -0,0 +1,18 @@ +id: swift-webview-config-allows-js-swift +valid: + - | + let prefs2 = WKWebpagePreferences() + prefs2.allowsContentJavaScript = true + prefs2.allowsContentJavaScript = false + let config = WKWebViewConfiguration() + config.defaultWebpagePreferences = prefs2 +invalid: + - | + let prefs = WKWebpagePreferences() + prefs.allowsContentJavaScript = true + let config = WKWebViewConfiguration() + config.defaultWebpagePreferences = prefs + - | + let preferences = WKPreferences() + preferences.javaScriptEnabled = true + preferences.javaScriptCanOpenWindowsAutomatically = false diff --git a/tests/swift/swift-webview-config-base-url-swift-test.yml b/tests/swift/swift-webview-config-base-url-swift-test.yml new file mode 100644 index 0000000..0986f10 --- /dev/null +++ b/tests/swift/swift-webview-config-base-url-swift-test.yml @@ -0,0 +1,12 @@ +id: swift-webview-config-base-url-swift +valid: + - | + let webview2 = WKWebView(...) + webview2.loadHTMLString(someHtmlString, baseURL: nil) +invalid: + - | + let webview = UIWebView(...) + webview.loadHTMLString(someHtmlString, baseURL: nil) + - | + let webview3 = UIWebView(...) + webview3.load(data, mimetype: "application/json", textEncodingName: "UTF8", baseURL: nil)