Merge pull request #11241 from egregius313/egregius313/webview-file-access

Java: Query to detect Android Webview file access
This commit is contained in:
Edward Minnix III
2022-12-12 11:12:26 -05:00
committed by GitHub
11 changed files with 150 additions and 2 deletions

View File

@@ -0,0 +1,65 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Allowing file access in an Android WebView can expose a device's file system to
the JavaScript running in that WebView. If the JavaScript contains
vulnerabilities or the WebView loads untrusted content, file access
allows an attacker to steal the user's data.
</p>
</overview>
<recommendation>
<p>When possible, do not allow file access. The file access settings
are disabled by default. You can explicitly disable file access by setting the
following settings to <code>false</code>:</p>
<ul>
<li><code>setAllowFileAccess</code></li>
<li><code>setAllowFileAccessFromFileURLs</code></li>
<li><code>setAllowUniversalAccessFromFileURLs</code></li>
</ul>
<p>If your application requires access to the file system, it is best to
avoid using <code>file://</code> URLs. Instead, use an alternative that
loads files via HTTPS, such
as <code>androidx.webkit.WebViewAssetLoader</code>.</p>
</recommendation>
<example>
<p>In the following (bad) example, the WebView is configured with settings
that allow local file access.</p>
<sample src="WebViewFileAccessUnsafe.java"/>
<p>In the following (good) example, the WebView is configured to disallow file access.</p>
<sample src="WebViewFileAccessSafe.java"/>
<p>
As mentioned previously, asset loaders can load files without file system
access. In the following (good) example, an asset loader is configured to
load assets over HTTPS.
</p>
<sample src="AssetLoaderExample.java"/>
</example>
<references>
<li>
Android documentation: <a href="https://developer.android.com/reference/android/webkit/WebSettings#setAllowFileAccess(boolean)">WebSettings.setAllowFileAccess</a>.
</li>
<li>
Android documentation: <a href="https://developer.android.com/reference/android/webkit/WebSettings#setAllowFileAccessFromFileURLs(boolean)">WebSettings.setAllowFileAccessFromFileURLs</a>.
</li>
<li>
Android documentation: <a href="https://developer.android.com/reference/android/webkit/WebSettings#setAllowUniversalAccessFromFileURLs(boolean)">WebSettings.setAllowUniversalAccessFromFileURLs</a>.
</li>
<li>
Android documentation: <a href="https://developer.android.com/reference/androidx/webkit/WebViewAssetLoader">WebViewAssetLoader</a>.
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,22 @@
/**
* @name Android WebSettings file access
* @kind problem
* @description Enabling access to the file system in a WebView allows attackers to view sensitive information.
* @id java/android-websettings-file-access
* @problem.severity warning
* @security-severity 6.5
* @precision medium
* @tags security
* external/cwe/cwe-200
*/
import java
import semmle.code.java.frameworks.android.WebView
from MethodAccess ma
where
ma.getMethod() instanceof CrossOriginAccessMethod and
ma.getArgument(0).(CompileTimeConstantExpr).getBooleanValue() = true
select ma,
"WebView setting " + ma.getMethod().getName() +
" may allow for unauthorized access of sensitive information."

View File

@@ -0,0 +1,15 @@
WebViewAssetLoader loader = new WebViewAssetLoader.Builder()
// Replace the domain with a domain you control, or use the default
// appassets.androidplatform.com
.setDomain("appassets.example.com")
.addPathHandler("/resources", new AssetsPathHandler(this))
.build();
webView.setWebViewClient(new WebViewClientCompat() {
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
return assetLoader.shouldInterceptRequest(request.getUrl());
}
});
webView.loadUrl("https://appassets.example.com/resources/www/index.html");

View File

@@ -0,0 +1,5 @@
WebSettings settings = view.getSettings();
settings.setAllowFileAccess(false);
settings.setAllowFileAccessFromURLs(false);
settings.setAllowUniversalAccessFromURLs(false);

View File

@@ -0,0 +1,5 @@
WebSettings settings = view.getSettings();
settings.setAllowFileAccess(true);
settings.setAllowFileAccessFromURLs(true);
settings.setAllowUniversalAccessFromURLs(true);