Compare commits
1 Commits
master
...
antonio/SO
Author | SHA1 | Date | |
---|---|---|---|
![]() |
db672993f6 |
@ -5237,7 +5237,6 @@
|
|||||||
"S5867": "sonar-kotlin 2.6.0.862",
|
"S5867": "sonar-kotlin 2.6.0.862",
|
||||||
"S5868": "sonar-kotlin 2.6.0.862",
|
"S5868": "sonar-kotlin 2.6.0.862",
|
||||||
"S5869": "sonar-kotlin 2.6.0.862",
|
"S5869": "sonar-kotlin 2.6.0.862",
|
||||||
"S6096": "sonar-security master",
|
|
||||||
"S6202": "sonar-kotlin 2.4.0.703",
|
"S6202": "sonar-kotlin 2.4.0.703",
|
||||||
"S6207": "sonar-kotlin 2.15.0.2579",
|
"S6207": "sonar-kotlin 2.15.0.2579",
|
||||||
"S6218": "sonar-kotlin 2.4.0.703",
|
"S6218": "sonar-kotlin 2.4.0.703",
|
||||||
@ -5260,7 +5259,6 @@
|
|||||||
"S6318": "sonar-kotlin 2.1.0.344",
|
"S6318": "sonar-kotlin 2.1.0.344",
|
||||||
"S6362": "sonar-kotlin 2.5.0.754",
|
"S6362": "sonar-kotlin 2.5.0.754",
|
||||||
"S6363": "sonar-kotlin 2.5.0.754",
|
"S6363": "sonar-kotlin 2.5.0.754",
|
||||||
"S6384": "sonar-security master",
|
|
||||||
"S6432": "sonar-kotlin 2.11.0.1828",
|
"S6432": "sonar-kotlin 2.11.0.1828",
|
||||||
"S6474": "sonar-kotlin master",
|
"S6474": "sonar-kotlin master",
|
||||||
"S6508": "sonar-kotlin 2.14.0.2352",
|
"S6508": "sonar-kotlin 2.14.0.2352",
|
||||||
|
8
rules/S7409/ask-yourself.adoc
Normal file
8
rules/S7409/ask-yourself.adoc
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
== Ask Yourself Whether
|
||||||
|
|
||||||
|
* The content in the WebView is fully trusted and secure.
|
||||||
|
* Potentially untrusted iframes could be loaded in the WebView.
|
||||||
|
* The JavaScript interface has to be exposed for the entire lifecycle of the WebView.
|
||||||
|
* The exposed Java object might be called by untrusted sources.
|
||||||
|
|
||||||
|
There is a risk if you answered yes to any of these questions.
|
5
rules/S7409/description.adoc
Normal file
5
rules/S7409/description.adoc
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
Using JavaScript interfaces in WebViews to expose Java objects is unsafe. Doing so allows JavaScript
|
||||||
|
to invoke Java methods, potentially giving attackers access to data or sensitive app functionality.
|
||||||
|
WebViews might include untrusted sources such as third-party iframes, making this functionality
|
||||||
|
particularly risky. As JavaScript interfaces are passed to every frame in the WebView, those iframes
|
||||||
|
are also able to access the exposed Java object.
|
2
rules/S7409/java/metadata.json
Normal file
2
rules/S7409/java/metadata.json
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
{
|
||||||
|
}
|
106
rules/S7409/java/rule.adoc
Normal file
106
rules/S7409/java/rule.adoc
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
include::../description.adoc[]
|
||||||
|
|
||||||
|
include::../ask-yourself.adoc[]
|
||||||
|
|
||||||
|
:setJavaScriptEnabledSnippet: webSettings.setJavaScriptEnabled(false)
|
||||||
|
|
||||||
|
include::../recommended.adoc[]
|
||||||
|
|
||||||
|
== Sensitive Code Example
|
||||||
|
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
public class ExampleActivity extends AppCompatActivity {
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
WebView webView = new WebView(this);
|
||||||
|
webView.getSettings().setJavaScriptEnabled(true);
|
||||||
|
webView.addJavascriptInterface(new JavaScriptBridge(), "androidBridge"); // Sensitive
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class JavaScriptBridge {
|
||||||
|
@JavascriptInterface
|
||||||
|
public String accessUserData(String userId) {
|
||||||
|
return getUserData(userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
== Compliant Solution
|
||||||
|
|
||||||
|
The most secure option is to disable JavaScript entirely. S6362 further explains why it should not be enabled
|
||||||
|
unless absolutely necessary.
|
||||||
|
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
public class ExampleActivity extends AppCompatActivity {
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
WebView webView = new WebView(this);
|
||||||
|
webView.getSettings().setJavaScriptEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
If possible, remove the JavaScript interface after it is no longer needed, or before loading any untrusted content.
|
||||||
|
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
public class ExampleActivity extends AppCompatActivity {
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
WebView webView = new WebView(this);
|
||||||
|
webView.getSettings().setJavaScriptEnabled(true);
|
||||||
|
|
||||||
|
webView.addJavascriptInterface(new JavaScriptBridge(), "androidBridge");
|
||||||
|
|
||||||
|
// Sometime later, before unsafe content is loaded, remove the JavaScript interface
|
||||||
|
webView.removeJavascriptInterface("androidBridge");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
If a JavaScript bridge must be used, consider using ``WebViewCompat.addWebMessageListener`` instead. This allows you to restrict
|
||||||
|
the origins that can send messages to the JavaScript bridge.
|
||||||
|
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
public class ExampleActivity extends AppCompatActivity {
|
||||||
|
private static final Set<String> ALLOWED_ORIGINS = Collections.singleton("https://example.com");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
WebView webView = new WebView(this);
|
||||||
|
webView.getSettings().setJavaScriptEnabled(true);
|
||||||
|
|
||||||
|
WebViewCompat.addWebMessageListener(
|
||||||
|
webView,
|
||||||
|
"androidBridge",
|
||||||
|
ALLOWED_ORIGINS, // Only allow messages from these origins
|
||||||
|
new WebMessageListener() {
|
||||||
|
@Override
|
||||||
|
public void onPostMessage(
|
||||||
|
WebView view,
|
||||||
|
WebMessageCompat message,
|
||||||
|
Uri sourceOrigin,
|
||||||
|
boolean isMainFrame,
|
||||||
|
JavaScriptReplyProxy replyProxy
|
||||||
|
) {
|
||||||
|
// Handle the message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
include::../see.adoc[]
|
@ -1,42 +1,2 @@
|
|||||||
{
|
{
|
||||||
"title": "Exposing Java objects through JavaScript interfaces is security-sensitive",
|
|
||||||
"type": "SECURITY_HOTSPOT",
|
|
||||||
"status": "ready",
|
|
||||||
"remediation": {
|
|
||||||
"func": "Constant\/Issue",
|
|
||||||
"constantCost": "30min"
|
|
||||||
},
|
|
||||||
"tags": [
|
|
||||||
"cwe",
|
|
||||||
"android"
|
|
||||||
],
|
|
||||||
"defaultSeverity": "Major",
|
|
||||||
"ruleSpecification": "RSPEC-7409",
|
|
||||||
"sqKey": "S7409",
|
|
||||||
"scope": "All",
|
|
||||||
"defaultQualityProfiles": [
|
|
||||||
"Sonar way"
|
|
||||||
],
|
|
||||||
"securityStandards": {
|
|
||||||
"OWASP Mobile": [
|
|
||||||
"M1"
|
|
||||||
],
|
|
||||||
"OWASP Mobile Top 10 2024": [
|
|
||||||
"M4",
|
|
||||||
"M8"
|
|
||||||
],
|
|
||||||
"OWASP Top 10 2021": [
|
|
||||||
"A5"
|
|
||||||
],
|
|
||||||
"CWE": [
|
|
||||||
79
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"quickfix": "unknown",
|
|
||||||
"code": {
|
|
||||||
"impacts": {
|
|
||||||
"SECURITY": "MEDIUM"
|
|
||||||
},
|
|
||||||
"attribute": "TRUSTWORTHY"
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,43 +1,10 @@
|
|||||||
Using JavaScript interfaces in WebViews to expose Java objects is unsafe. Doing so allows JavaScript
|
include::../description.adoc[]
|
||||||
to invoke Java methods, potentially giving attackers access to data or sensitive app functionality.
|
|
||||||
WebViews might include untrusted sources such as third-party iframes, making this functionality
|
|
||||||
particularly risky. As JavaScript interfaces are passed to every frame in the WebView, those iframes
|
|
||||||
are also able to access the exposed Java object.
|
|
||||||
|
|
||||||
== Ask Yourself Whether
|
include::../ask-yourself.adoc[]
|
||||||
|
|
||||||
* The content in the WebView is fully trusted and secure.
|
:setJavaScriptEnabledSnippet: webSettings.javaScriptEnabled = false
|
||||||
* Potentially untrusted iframes could be loaded in the WebView.
|
|
||||||
* The JavaScript interface has to be exposed for the entire lifecycle of the WebView.
|
|
||||||
* The exposed Java object might be called by untrusted sources.
|
|
||||||
|
|
||||||
There is a risk if you answered yes to any of these questions.
|
include::../recommended.adoc[]
|
||||||
|
|
||||||
== Recommended Secure Coding Practices
|
|
||||||
|
|
||||||
=== Disable JavaScript
|
|
||||||
|
|
||||||
If it is possible to disable JavaScript in the WebView, this is the most secure option. By default,
|
|
||||||
JavaScript is disabled in a WebView, so ``webSettings.setJavaScriptEnabled(false)`` does not need to
|
|
||||||
be explicitly called. Of course, sometimes it is necessary to enable JavaScript, in which case the
|
|
||||||
following recommendations should be considered.
|
|
||||||
|
|
||||||
=== Remove JavaScript interface when loading untrusted content
|
|
||||||
|
|
||||||
JavaScript interfaces can be removed at a later point. It is recommended to remove the JavaScript
|
|
||||||
interface when it is no longer needed. If it is needed for a longer time, consider removing it before
|
|
||||||
loading untrusted content. This can be done by calling ``webView.removeJavascriptInterface("interfaceName")``.
|
|
||||||
|
|
||||||
A good place to do this is inside the ``shouldInterceptRequest`` method of a ``WebViewClient``, where you can
|
|
||||||
check the URL or resource being loaded and remove the interface if the content is untrusted.
|
|
||||||
|
|
||||||
=== Alternative methods to implement native bridges
|
|
||||||
|
|
||||||
If a native bridge has to be added to the WebView, and it is impossible to remove it at a later point,
|
|
||||||
consider using an alternative method that offers more control over the communication flow.
|
|
||||||
``WebViewCompat.postWebMessage``/``WebViewCompat.addWebMessageListener`` and ``WebMessagePort.postMessage``
|
|
||||||
offer more ways to validate incoming and outgoing messages, such as by being able to restrict the origins
|
|
||||||
that can send messages to the JavaScript bridge.
|
|
||||||
|
|
||||||
== Sensitive Code Example
|
== Sensitive Code Example
|
||||||
|
|
||||||
@ -112,7 +79,9 @@ class ExampleActivity : AppCompatActivity() {
|
|||||||
webView.settings.javaScriptEnabled = true
|
webView.settings.javaScriptEnabled = true
|
||||||
|
|
||||||
WebViewCompat.addWebMessageListener(
|
WebViewCompat.addWebMessageListener(
|
||||||
webView, "androidBridge", ALLOWED_ORIGINS, // Only allow messages from these origins
|
webView,
|
||||||
|
"androidBridge",
|
||||||
|
ALLOWED_ORIGINS, // Only allow messages from these origins
|
||||||
object : WebViewCompat.WebMessageListener {
|
object : WebViewCompat.WebMessageListener {
|
||||||
override fun onPostMessage(
|
override fun onPostMessage(
|
||||||
view: WebView,
|
view: WebView,
|
||||||
@ -129,14 +98,4 @@ class ExampleActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
|
||||||
== See
|
include::../see.adoc[]
|
||||||
|
|
||||||
* Android Documentation - https://developer.android.com/privacy-and-security/risks/insecure-webview-native-bridges[Insecure WebView native bridges]
|
|
||||||
* Android Documentation - https://developer.android.com/reference/androidx/webkit/WebViewCompat[WebViewCompat API reference]
|
|
||||||
* OWASP - https://owasp.org/Top10/A05_2021-Security_Misconfiguration/[Top 10 2021 Category A5 - Security Misconfiguration]
|
|
||||||
* OWASP - https://owasp.org/www-project-mobile-top-10/2023-risks/m4-insufficient-input-output-validation.html[Mobile Top 10 2024 Category M4 - Insufficient Input/Output Validation]
|
|
||||||
* OWASP - https://owasp.org/www-project-mobile-top-10/2023-risks/m8-security-misconfiguration.html[Mobile Top 10 2024 Category M8 - Security Misconfiguration]
|
|
||||||
* CWE - https://cwe.mitre.org/data/definitions/79[CWE-79 - Improper Neutralization of Input During Web Page Generation]
|
|
||||||
|
|
||||||
=== Related rules
|
|
||||||
* S6362 - Enabling JavaScript support for WebViews is security-sensitive
|
|
0
rules/S7409/message.adoc
Normal file
0
rules/S7409/message.adoc
Normal file
@ -1 +1,42 @@
|
|||||||
{}
|
{
|
||||||
|
"title": "Exposing Java objects through JavaScript interfaces is security-sensitive",
|
||||||
|
"type": "SECURITY_HOTSPOT",
|
||||||
|
"status": "ready",
|
||||||
|
"remediation": {
|
||||||
|
"func": "Constant\/Issue",
|
||||||
|
"constantCost": "30min"
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
"cwe",
|
||||||
|
"android"
|
||||||
|
],
|
||||||
|
"defaultSeverity": "Major",
|
||||||
|
"ruleSpecification": "RSPEC-7409",
|
||||||
|
"sqKey": "S7409",
|
||||||
|
"scope": "All",
|
||||||
|
"defaultQualityProfiles": [
|
||||||
|
"Sonar way"
|
||||||
|
],
|
||||||
|
"securityStandards": {
|
||||||
|
"OWASP Mobile": [
|
||||||
|
"M1"
|
||||||
|
],
|
||||||
|
"OWASP Mobile Top 10 2024": [
|
||||||
|
"M4",
|
||||||
|
"M8"
|
||||||
|
],
|
||||||
|
"OWASP Top 10 2021": [
|
||||||
|
"A5"
|
||||||
|
],
|
||||||
|
"CWE": [
|
||||||
|
79
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"quickfix": "partial",
|
||||||
|
"code": {
|
||||||
|
"impacts": {
|
||||||
|
"SECURITY": "MEDIUM"
|
||||||
|
},
|
||||||
|
"attribute": "TRUSTWORTHY"
|
||||||
|
}
|
||||||
|
}
|
25
rules/S7409/recommended.adoc
Normal file
25
rules/S7409/recommended.adoc
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
== Recommended Secure Coding Practices
|
||||||
|
|
||||||
|
=== Disable JavaScript
|
||||||
|
|
||||||
|
If it is possible to disable JavaScript in the WebView, this is the most secure option. By default,
|
||||||
|
JavaScript is disabled in a WebView, so ``{setJavaScriptEnabledSnippet}`` does not need to
|
||||||
|
be explicitly called. Of course, sometimes it is necessary to enable JavaScript, in which case the
|
||||||
|
following recommendations should be considered.
|
||||||
|
|
||||||
|
=== Remove JavaScript interface when loading untrusted content
|
||||||
|
|
||||||
|
JavaScript interfaces can be removed at a later point. It is recommended to remove the JavaScript
|
||||||
|
interface when it is no longer needed. If it is needed for a longer time, consider removing it before
|
||||||
|
loading untrusted content. This can be done by calling ``webView.removeJavascriptInterface("interfaceName")``.
|
||||||
|
|
||||||
|
A good place to do this is inside the ``shouldInterceptRequest`` method of a ``WebViewClient``, where you can
|
||||||
|
check the URL or resource being loaded and remove the interface if the content is untrusted.
|
||||||
|
|
||||||
|
=== Alternative methods to implement native bridges
|
||||||
|
|
||||||
|
If a native bridge has to be added to the WebView, and it is impossible to remove it at a later point,
|
||||||
|
consider using an alternative method that offers more control over the communication flow.
|
||||||
|
``WebViewCompat.postWebMessage``/``WebViewCompat.addWebMessageListener`` and ``WebMessagePort.postMessage``
|
||||||
|
offer more ways to validate incoming and outgoing messages, such as by being able to restrict the origins
|
||||||
|
that can send messages to the JavaScript bridge.
|
11
rules/S7409/see.adoc
Normal file
11
rules/S7409/see.adoc
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
== See
|
||||||
|
|
||||||
|
* Android Documentation - https://developer.android.com/privacy-and-security/risks/insecure-webview-native-bridges[Insecure WebView native bridges]
|
||||||
|
* Android Documentation - https://developer.android.com/reference/androidx/webkit/WebViewCompat[WebViewCompat API reference]
|
||||||
|
* OWASP - https://owasp.org/Top10/A05_2021-Security_Misconfiguration/[Top 10 2021 Category A5 - Security Misconfiguration]
|
||||||
|
* OWASP - https://owasp.org/www-project-mobile-top-10/2023-risks/m4-insufficient-input-output-validation.html[Mobile Top 10 2024 Category M4 - Insufficient Input/Output Validation]
|
||||||
|
* OWASP - https://owasp.org/www-project-mobile-top-10/2023-risks/m8-security-misconfiguration.html[Mobile Top 10 2024 Category M8 - Security Misconfiguration]
|
||||||
|
* CWE - https://cwe.mitre.org/data/definitions/79[CWE-79 - Improper Neutralization of Input During Web Page Generation]
|
||||||
|
|
||||||
|
=== Related rules
|
||||||
|
* S6362 - Enabling JavaScript support for WebViews is security-sensitive
|
Loading…
x
Reference in New Issue
Block a user