Android WebView Class Poses Significant Security Risk
Tencent Security Labs recently reported a vulnerability that exists across some common apps. The report can be found at http://www.cnvd.org.cn/webinfo/show/4365. The issue, which has been around since 2014, has to do with the misconfiguration or misuse of the WebView class.
The Android WebView class is used to display HTML pages such as the UI or online content. WebView uses the WebKit rendering engine, which is included in many web browsers. The engine allows the user to navigate forward and backward, zoom in and out on a web page, and process JavaScript in the HTML document.
The following is an example of using WebView:
WebView webView = findViewById(R.id.webView);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.loadUrl("http://www.example.com");
JavaScipt is disabled in WebView by default, though the user can enable it. WebView settings also provide methods to interact with other content, such as:
- setAllowFileAccess
Enables or disables file access in WebView. Note that the assets and resources are still accessible even if file access is disabled.
- setAllowFileAccessFromFileURLs
Enables or disables the JavaScript in the file scheme URL from accessing content from other file scheme URLs. This setting is overwritten by setAllowUniversalAccessFromFileURLs
- setAllowUniversalAccessFromFileURLs
Enables or disables the JavaScript in the file scheme URL from accessing content from any other source.
In web applications, there is a “same-origin policy,” which is used to restrict JavaScript on the page from accessing a user’s most important data. The browser’s policy is to check for protocol, host and port in URIs.
A brief sample of URIs compared with URL http: //www.example.com/index.html under the same-origin policy are shown below:
URL same-origin or not, and description
http: //www.example.com/index2.html ; same-origin
https: //www.example.com/index.html ; Not same-origin, protocol is different
http: //example.com/index.html ; Not same-origin, host is different
http: //www.example.com:88/index.html ; Not same-origin, port is different
file:///data/local/tmp/index.html ; Not same-origin, protocol and host are different
WebView implements the same-origin policy. If the JavaScript is used in the HTTP scheme, it can’t access the file scheme URLs. Normally, Android apps are running in separate processes. For instance, App A is not able to access the private data for App B, and vice versa. However, if setAllowFileAccess and setAllowUniversalAccessFromFileURLs are enabled, App A can run the exported activity from App B and pass the malicious file scheme URLs to the WebView in App B to access the private files in App B.
App B contains WebView which accepts the following parameter url:
WebView webView = findViewById(R.id.webView);
webView.loadUrl(url);
If App A passes a file scheme url “file:///data/local/tmp/index.html” as the parameter “url” for the webView.loadUrl(url) in App B
The index.html file has the following content:
<html>
<head>
<script>
function readfile() {
alert(document.getElementById('iframe').contentDocument.body.firstChild.innerHTML);
}
</script>
</head>
<body>
<iframe id='iframe' src = "file:///data/data/com.test.webv/abc.txt" onload='readfile()'> </iframe>
</body>
</html>
App A accesses the private file from App B “/data/data/com.test.webv/abc.txt”. In the above sample, the attacker must have the ability to drop the malicious HTML document into the user’s device.
Workarounds for this potential WebView vulnerability include:
- Disable file scheme URLs in the app if file access is not needed. This can be accomplished by setting methods setAllowFileAccess as false. Since files in assets and res folder are not affected by these settings, some fixed HTML can be placed in these folders.
- Check for file scheme URLs to eliminate directory traversal attacks.
- If the app doesn’t use JavaScript in a WebView, set method setJavaScriptEnabled as false.
- If activity export is not needed, set android:exported=”false” in the Activity tag in Manifest. Otherwise check the passed parameters for the WebView.