Опасная комбинация настроек WebView: JavaScript и доступ к локальным файлам
![]() |
Критичность: ВЫСОКИЙ |
| Способ обнаружения: DAST, WEBVIEW |
Описание
Дефект возникает, когда в WebView одновременно включены исполнение JavaScript и доступ к локальной файловой системе. Опасную комбинацию образуют флаги:
setJavaScriptEnabled(true)— исполнение JavaScript;setAllowFileAccess(true)— доступ к схемеfile://;setAllowFileAccessFromFileURLs(true)— страница, открытая поfile://, может читать другие файлы поfile://;setAllowUniversalAccessFromFileURLs(true)— страница, открытая поfile://, может обращаться к контенту любого источника (обход Same-Origin Policy).
В такой конфигурации JavaScript, исполняемый в WebView, получает возможность читать произвольные файлы из песочницы приложения и отправлять их на внешний сервер.
Пример небезопасного кода:
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setAllowFileAccess(true);
settings.setAllowFileAccessFromFileURLs(true);
settings.setAllowUniversalAccessFromFileURLs(true);
webView.loadUrl(externalUrl); // при подгрузке постороннего контента — критично
Проблема
- Чтение приватных файлов приложения. JavaScript может прочитать файлы песочницы (
/data/data/<pkg>/...): SQLite-базы, токены, настройки — и эксфильтровать их. - Обход Same-Origin Policy.
setAllowUniversalAccessFromFileURLs(true)снимает изоляцию источников, позволяя локальной странице обращаться к произвольным ресурсам, включая удалённые. - Усиление XSS. При наличии XSS в загруженном контенте указанная комбинация превращает межсайтовый скриптинг в кражу локальных данных.
- Эксплуатация через сторонний
file://. Если злоумышленник может подсунуть в WebViewfile://-URL (например, через экспортируемый компонент или скачанный HTML), он исполнит свой скрипт с правами доступа к файлам приложения.
Рекомендации
-
Отключите доступ к файловой системе для веб-контента. Это основная мера; задавайте флаги явно (дефолты зависят от версии API:
setAllowFileAccessFromFileURLs/setAllowUniversalAccessFromFileURLs—falseначиная с API 16;setAllowFileAccess—falseлишь приtargetSdkVersion ≥ 30, иначеtrue; полагаться на дефолты не следует): -
Никогда не сочетайте
setJavaScriptEnabled(true)с доступом кfile://при загрузке недоверенного или удалённого контента.AllowUniversalAccessFromFileURLs(true)не должен использоваться в production ни при каких условиях. -
Отдавайте локальные ресурсы через
WebViewAssetLoader. Он обслуживает упакованные файлы и контент через виртуальныйhttps-доменappassets.androidplatform.net, сохраняя Same-Origin Policy и не открывая доступ к произвольнымfile://:WebViewAssetLoader loader = new WebViewAssetLoader.Builder() .addPathHandler("/assets/", new WebViewAssetLoader.AssetsPathHandler(this)) .addPathHandler("/res/", new WebViewAssetLoader.ResourcesPathHandler(this)) .build(); webView.setWebViewClient(new WebViewClientCompat() { @Override public WebResourceResponse shouldInterceptRequest(WebView v, WebResourceRequest req) { return loader.shouldInterceptRequest(req.getUrl()); } }); webView.loadUrl("https://appassets.androidplatform.net/assets/index.html"); -
Изолируйте сценарии, где
file://действительно необходим. Используйте для них отдельный экземпляр WebView с выключенным JavaScript и без сетевого доступа; не смешивайте локальный и удалённый контент в одном WebView. -
Контролируйте загружаемый путь. Если путь к файлу формируется динамически — канонизируйте его и проверяйте, что он находится внутри разрешённого каталога (защита от Path Traversal). Запрещайте
file://-URL, пришедшие из внешних источников (Intent, deeplink). -
Не храните секреты в файлах, доступных WebView. Чувствительные данные держите в защищённых хранилищах (
EncryptedSharedPreferences, Android Keystore), а не в файлах, которые может прочитать веб-контент. -
Усильте защиту на стороне страницы. Для подконтрольного контента задавайте
Content-Security-Policyи запрещайте загрузку внешних ресурсов, чтобы ограничить последствия возможной инъекции.
Ссылки
- https://developer.android.com/privacy-and-security/risks/webview-unsafe-file-inclusion
- https://developer.android.com/reference/androidx/webkit/WebViewAssetLoader
- https://developer.android.com/reference/android/webkit/WebSettings#setAllowUniversalAccessFromFileURLs(boolean)
- https://mas.owasp.org/MASTG/tests/android/MASVS-PLATFORM/MASTG-TEST-0033/
- https://cwe.mitre.org/data/definitions/749.html
- https://cwe.mitre.org/data/definitions/200.html
- https://cwe.mitre.org/data/definitions/79.html
- https://cwe.mitre.org/data/definitions/22.html
