Monday, November 5, 2012

Android WebView Security -- a few notes

[1] Javascript
By default Javascript is disabled in Android -- however, developers can choose
to turn them on in `WebSettings`. Do not turn them on unless absolutely necessary.
WebView myWebView = (WebView) findViewById(;

[2] addJavascriptInterface
A lot of code uses `addJavascriptInterface`. Using the API presents a wide range of
security issues ranging from attackers executing native code by taking advantage of
an XSS vulnerability to attackers executing native code with a malicious child iframe.
Please note that if you can avoid using the API, do so.
Below you can find the various attacks possible along with solutions suggested for the
same :-

- Attackers taking advantage of an XSS vulnerability
- If you are using the `addJavascriptInterface` API, it is safe to assume that you
have overridden the defaults and have turned on JavaScript in your WebView using the
API discussed in [1]. This exposes your application to XSS, hence its absolutely
critical that you filter and encode untrusted input.

- Viewing an attacker controlled website in the WebView
- If an attacker can cause a WebView to visit a malicious web application, the attacker
could use the exported interfaces to execute native code on the device.

- A variation of this attack might have a malicious web application that has the
legitimate web application as a child i-frame. Assuming that the child i-frame interacts
with the exported interfaces, the responses(that might contain sensitive data) are
sent back to the parent i-frame by injecting javascript into the WebView.

- A solution to the above mentioned problems would be to navigate to domains outside
the expected domain, by using `shouldOverrideUrlLoading`, checking if the domain is
allowed and using the default Android browser, rather than the WebView to open the
URL if it is not trusted.
This could be done by creating an Intent and sending it over.

Overriding the URL can be done as follows :-
public boolean shouldOverrideUrlLoading(WebView wView, String url)
String hostName = Uri.parse(url).getHost();
if( hostName != "" )
Uri uriUrl = Uri.parse("");
Intent launchDefaultBrowser = new Intent(Intent.ACTION_VIEW, uriUrl);
return true;
return false;
- [WARNING] shouldOverrideUrlLoading does not intercept URL loading from an IFRAME
or src attribute or XmlHttpRequests.
BE very careful when I-Framing a child. Do not I-Frame over HTTP.

public WebResourceResponse shouldInterceptRequest(final WebView view, String url)
return getResourceManually();
// let the resource load normally
return super.shouldInterceptRequest(view, url);
private WebResourceResponse getResourceManually()
   return getUtf8EncodedWebResourceResponse(new StringBufferInputStream("Blah!"));

[3] Plugin support for WebViews
- If your application does not use plugins such as Flash, disable them explicitly. This
prevents attackers from compromising your application via a 3rd party plugin.

_ You can disable plugins using the following snippet of code

webview = new WebView(this);

- If you need a particular plugin you can use setPluginState

webview = new WebView(this);

[4] Disabling the local file system access
- By default the local file system access is enabled for WebViews. Resources and assets
can be accessed as file:///resource_id or file:///asset_name respectively.
It is a good idea to turn this off in order to reduce the impact of a possible compromise.

- You can disable file system access as follows

webview = new WebView(this);

- If there are resources that your WebView needs to access you can choose to allow only
requests from a trusted domain to access resources by a solution similar to that
presented in [2].

Reference :-

No comments:

Post a Comment