Same Origin Policy and the Android WebView

First of all, let me say that all that follows is public knowledge and is somewhat described in the Android docs. However, I haven’t seen much discussion, so I thought it’s a good idea to write a blog post.

####Same Origin Policy When a page is loaded into a WebView to be displayed, all code in this page runs “in the context” of that page (its origin). The Same Origin Policy (SOP) is a mechanism that restricts javascript running in the context of one origin to access objects from another origin.

####Local File Access Things get complicated when a webview loads an HTML page from the local file system, either by design or by mistake.

Up until Android API 16 (version 4.1) Android WebViews treat everything loaded via a file:// URL like it belongs to the same origin, for Same Origin Policy purposes.

This means that javascript inside HTML loaded via a file:// URL can read any file on the filesystem that the application can, including any files in the application’s internal storage.

#####Why is this a problem? There are many ‘attacks’ that are enabled because of this behavior. The following require that the WebView component has JavaScript enabled.

######HTML files in insecure locations Say that a WebView loads a local HTML file from an insecure location (e.g. the SDcard) using the file:// scheme.

Since the file is writable, an attacker can edit the HTML file and include malicious JavaScript code. This JS code will be able to read all private application files, including e.g. passwords saved in a shared preferences file. Then, it can save the retrieved file to SDcard to be picked up later, or send it back via the internet.

######HTML files loading JS insecurely Say that a WebView loads a local HTML file, which is stored in private store, thus cannot be edited by a third party application. However, this local HTML file also uses <script src=""> to fetch JavaScript from another website using HTTP. This remotely-retrieved JS code will also run using the “file” origin.

If the attacker can perform a Man-in-The-Middle attack on the the request that fetches the remote JS file, he can insert his code, which will be able to read private application files.

######WebViews accepting URL via non-validated intents WebView components commonly retrieve the URL to be loaded into the webview using intents from a different part of the application. If a malicious application is able to send an intent with a malicious URL, then the WebView can be forced to load an attacker’s local HTML file, enabling the file-retrieval attack.

In all these situations, of course, if the webview also supports a javascript-to-java interface, code execution can also be possible in some Android versions.

######Mitigation There are multiple mitigation techniques. First, never enable JavaScript unless absolutely necessary. Use WebSettings.setJavaScriptEnabled(false) to be sure. Second, if receiving the URL to be loaded via an intent, make sure to validate the URL and the sender - set components to non-exported or apply permissions as needed.

Third, you can (and should) disable local file access support, unless absolutely nesecary. Access to the local file system (e.g. loading a file in a WebView) is enabled by calling WebSettings.setAllowFileAccess(). By default, WebViews have file system access enabled. Use WebSettings.setAllowFileAccess(false).

Finally, also use WebSettings.setAllowFileAccessFromFileURLs(false) WebSettings.setAllowUniversalAccessFromFileURLs(false). These methods exist in API 16 and later and are false by default, but it’s probably a good idea to make sure of the defaults.

Also note that these settings are relevant only for JavaScript access to file scheme resources. Other access to these resources, e.g. from image HTML elements, is always allowed.

~TODO: add some example code

mobile security, static & dynamic analysis, automation, payments

London, UK