Проброс произвольных данных в контекст WebView
![]() |
Критичность: ВЫСОКИЙ |
| Способ обнаружения: DAST, WEBVIEW |
Описание
Дефект возникает, когда данные из недоверенного источника (Intent, deeplink, файл, сетевой ответ, межпроцессное взаимодействие) попадают в WebView без валидации — через методы загрузки и исполнения: loadUrl, loadData, loadDataWithBaseURL, evaluateJavascript или через @JavascriptInterface-мост. Stingray перехватывает аргументы этих методов в рантайме и фиксирует попадание в них контролируемых извне значений.
Пример уязвимого кода:
// адрес и/или данные приходят из внешнего Intent
String url = getIntent().getStringExtra("target_url");
webView.loadUrl(url); // открытие произвольного URL
String html = getIntent().getStringExtra("html");
webView.loadData(html, "text/html", "UTF-8"); // рендеринг произвольного HTML/JS
Особенно опасно, когда такой WebView находится в экспортируемом компоненте: любой сторонний процесс может прислать Intent и заставить приложение открыть подконтрольную страницу.
Проблема
- Открытие произвольного URL. Контролируемый извне адрес позволяет загрузить подконтрольную злоумышленнику страницу — для фишинга от имени приложения или эксплуатации JavaScript-мостов.
- Инъекция HTML/JavaScript. Передача произвольного HTML в
loadData/loadDataWithBaseURL/evaluateJavascriptведёт к исполнению постороннего JavaScript в контексте приложения (XSS). - Кража данных и вызов нативных методов. В связке с
@JavascriptInterfaceинъекция позволяет вызывать нативный код и выводить наружу данные приложения. - Обход бизнес-логики и Same-Origin. Подмена
baseURLвloadDataWithBaseURLменяет контекст происхождения страницы и может обойти клиентские проверки, а также получить доступ к данным «доверенного» домена. - Опасные схемы. Передача
javascript:,file:,data:,content:URL открывает исполнение кода или доступ к локальным ресурсам.
Рекомендации
-
Считайте недоверенным любой внешний ввод. Данные из Intent, deeplink, IPC, файлов и сети должны проходить валидацию до передачи в
loadUrl/loadData/loadDataWithBaseURL/evaluateJavascript. -
Применяйте allow-list для адресов. Проверяйте схему и хост по белому списку; разрешайте только
httpsи доверенные домены, отклоняйтеjavascript:,file:,data:,content:и неизвестные схемы: -
Ограничьте навигацию внутри WebView. Реализуйте
WebViewClient.shouldOverrideUrlLoading()(иshouldInterceptRequest()), пропуская только разрешённые URL, а остальные — открывая во внешнем браузере или блокируя. -
Не экспортируйте компоненты с WebView без необходимости. Для
Activity/Service, открывающих WebView по данным из Intent, задавайтеandroid:exported="false"либо защитуpermissionуровняsignature; проверяйте вызывающую сторону. -
Не передавайте недоверенный HTML. Формируйте разметку из доверенных шаблонов на стороне приложения и экранируйте подставляемые значения. В
loadDataWithBaseURLиспользуйте безопасныйbaseURLи корректную кодировку; не задавайтеbaseURLдоверенного домена для недоверенного контента. -
Передавайте данные безопасно. Для канала native↔web используйте
WebMessagePort/postWebMessage()иWebViewCompat.addWebMessageListener()сallowedOriginRules; при необходимости подставить значение в скрипт — экранируйте черезJSONObject.quote()(не склейкой строк). -
Минимизируйте JavaScript-мосты и не выставляйте чувствительные методы через
@JavascriptInterface. -
Не отключайте проверку TLS. В
onReceivedSslError()вызывайтеhandler.cancel(). Запретите смешанный контент:setMixedContentMode(MIXED_CONTENT_NEVER_ALLOW). -
Усильте защиту контента. Включите Google Safe Browsing и задавайте строгий
Content-Security-Policyдля подконтрольных страниц, чтобы ограничить последствия инъекции.
Ссылки
- https://developer.android.com/develop/ui/views/layout/webapps/webview
- https://developer.android.com/privacy-and-security/risks/webview-unsafe-javascript-interface
- https://developer.android.com/reference/androidx/webkit/WebViewCompat
- https://developer.android.com/privacy-and-security/risks/unsafe-uri-loading
- https://mas.owasp.org/MASTG/tests/android/MASVS-PLATFORM/MASTG-TEST-0033/
- https://cwe.mitre.org/data/definitions/601.html
- https://cwe.mitre.org/data/definitions/79.html
- https://cwe.mitre.org/data/definitions/749.html
- https://cwe.mitre.org/data/definitions/20.html
