(THIS CODING RULE OR GUIDELINE IS UNDER CONSTRUCTION)

For API level JELLY_BEAN or below, allowing an app to use the addJavascriptInterface method with untrusted content in a WebView leaves the app vulnerable to scripting attacks using reflection to access public methods from JavaScript.  Untrusted content examples include content from any HTTP URL (as opposed to HTTPS) and user-provided content. The method addJavascriptInterface(Object, String) is called from the android.webkit.WebView class. Sensitive data and app control should not be exposed to scripting attacks.

Noncompliant Code Example

This noncompliant code example shows an application that calls the addJavascriptInterface() method, and hence is not secure for API level JELLY_BEAN and lower.

WebView webView = new WebView(this);
setContentView(webView);
...
class JsObject {
     private String sensitiveInformation;

     ...
     public String toString() { return sensitiveInformation; }

}
 webView.addJavascriptInterface(new JsObject(), "injectedObject");
 webView.loadData("", "text/html", null);
 webView.loadUrl("http://www.example.com");

JavaScript can now control the host. Java reflection could be used to access any of the public methods of an injected object, using the permissions of the app.

Compliant Solution #1

Compliant code could refrain from calling the addJavascriptInterface() method.

WebView webView = new WebView(this);
setContentView(webView);
...

Compliant Solution #2

Another compliant solution is to specify in the app's manifest that the app is only for API levels JELLY_BEAN_MR1 and above. For these API levels, only public methods that are annotated with JavascriptInterface can be accessed from JavaScript. API level 17 is JELLY_BEAN_MR1.

<manifest>
<uses-sdk android:minSdkVersion="17" />
...

</manifest>

Applicability

Android Version Applicability 

Applies to Android API versions 16 (JELLY_BEAN) and below.

API Levels

16

Risk Assessment

Allowing an app to provide access to the addJavascriptInterface method in a WebView which could contain untrusted content may leave it open to scripting attacks that could corrupt the host, for API level JELLY_BEAN and below.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

DRD13-J

High

Probable

Medium

P12

L1

Automated Detection

Automatic detection of a call to the addJavascriptInterface() method in a WebView is straightforward. Similarly, it is straightforward to automatically ensure that the minimum API is set to JELLY_BEAN_MR1 in the app manifest. Automatic determination of whether the WebView could contain untrusted content may be impossible for some applications.

Related Guidelines

Bibliography

 


4 Comments

  1. This should be scoped and titled so it is clear to be talking specifically about addJavascriptInterface for Javascript-to-native bridging.  Very different than  just javascript in a webview alone.

    Wrong:  "it is possible to enable it [JavaScript ] by using the method addJavascriptInterface(Object, String"

    1. Why do you say that the sentence about enabling JavaScript by using the addJavascriptInterface is wrong?

      The API for this methods says:

      Injects the supplied Java object into this WebView. The object is injected into the JavaScript context of the main frame, using the supplied name. This allows the Java object's methods to be accessed from JavaScript. For applications targeted to API level JELLY_BEAN_MR1 and above, only public methods that are annotated with JavascriptInterface can be accessed from JavaScript. For applications targeted to API level JELLY_BEAN or below, all public methods (including the inherited ones) can be accessed, see the important security note below for implications.

      and

      This method can be used to allow JavaScript to control the host application. This is a powerful feature, but also presents a security risk for applications targeted to API level JELLY_BEAN or below, because JavaScript could use reflection to access an injected object's public fields. Use of this method in a WebView containing untrusted content could allow an attacker to manipulate the host application in unintended ways, executing Java code with the permissions of the host application. Use extreme care when using this method in a WebView which could contain untrusted content.

      Is your point that the risk has been mitigated at level JELLY_BEAN_MR1 and above?

      Thanks.

    1. The title of this is wrong, "Do not allow JavaScript in Web Apps".  First, it's not "Web Apps" but "Web Views" in mobile apps (that alone is confusing).  But even then, the entire discussion is about the API addJavaScriptInterface which has to do with JavaScript to Native Bridgingnot JavaScript within WebViews in general.  They are separate concepts and risks.  e.g. https://developer.android.com/reference/android/webkit/WebSettings.html#setJavaScriptEnabled(boolean) vs. https://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object, java.lang.String)
    2. Second, the specific text that I pointed out is wrong.  It currently says, "it is possible to enable it [javascript] by using the method addJavascriptInterface(Object, String) from the android.webkit.WebView class"  This is not correct.  Enabling javascript in a WebView is done via the https://developer.android.com/reference/android/webkit/WebSettings.html#setJavaScriptEnabled(boolean) API.  Enabling JavaScript to Native Bridging is done using the addJavascriptInterface API.  They are not the same thing but they are being inappropriately conflated.  But because these concepts are conflated, there is a lot more text on the page that is also wrong for the same reason.

    Now, regarding the risk of addJavascriptInterface – most definitely you need to take into account the SDK level because it is only vulnerable in the older platforms.  The admonition currently says, "Compliant code should not call the addJavascriptInterface() method"  But that misses the nuanced distinction that the vulnerability only applies to older SDK levels (which are still a vast majority of the overall Android community - 64.2% as of today https://developer.android.com/about/dashboards/index.html?utm_source=ausdroid.net)

    1. Unknown User (lflynn)

      Thank you for your initial comments, and then your quick (under 15 minutes!) response to Fred's question, clear description of the issues, and helpful links. I have revised accordingly, and would welcome your review of the changes. Thanks again!