CodeQL documentation

Android WebSettings file access

ID: java/android/websettings-file-access
Kind: problem
Security severity: 6.5
Severity: warning
Precision: medium
Tags:
   - security
   - external/cwe/cwe-200
Query suites:
   - java-security-extended.qls
   - java-security-and-quality.qls

Click to see the query in the CodeQL repository

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.

Recommendation

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 false:

  • setAllowFileAccess

  • setAllowFileAccessFromFileURLs

  • setAllowUniversalAccessFromFileURLs If your application requires access to the file system, it is best to avoid using file:// URLs. Instead, use an alternative that loads files via HTTPS, such as androidx.webkit.WebViewAssetLoader.

Example

In the following (bad) example, the WebView is configured with settings that allow local file access.

WebSettings settings = view.getSettings();

settings.setAllowFileAccess(true);
settings.setAllowFileAccessFromURLs(true);
settings.setAllowUniversalAccessFromURLs(true);

In the following (good) example, the WebView is configured to disallow file access.

WebSettings settings = view.getSettings();

settings.setAllowFileAccess(false);
settings.setAllowFileAccessFromURLs(false);
settings.setAllowUniversalAccessFromURLs(false);

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.

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");

References