Категория OWASP: MASVS-PLATFORM: Взаимодействие платформ
Обзор
A native bridge, sometimes known as a JavaScript bridge, is a mechanism that facilitates communication between a WebView and native Android code, achieved by using the addJavascriptInterface method. This allows for two-way communication between JavaScript code running in the WebView and the Android application's Java code. The addJavascriptInterface method exposes a Java object to all of a WebView's frames, and any frame can access the object name and call methods on it. However, there is no mechanism for the application to verify the origin of the calling frame within the WebView, which raises security concerns as the trustworthiness of the content remains indeterminate.
Также можно реализовать нативный мост с использованием каналов сообщений HTML, применяя методы Android WebViewCompat.postWebMessage или WebMessagePort.postMessage для связи с JavaScript-объектом Window.postMessage . WebViewCompat.postWebMessage и WebMessagePort.postMessage могут принимать сообщения JavaScript, отправленные через Window.postMessage , которые будут выполняться внутри WebView.
С мостами, построенными из местных материалов, связаны многочисленные риски:
- Мосты на основе JavascriptInterface:
- Метод
addJavascriptInterfaceвнедряет предоставленный Java-объект в каждый фрейм WebView, включая iframe, что делает его уязвимым для атак со стороны злоумышленников, внедряющих фреймы в легитимный веб-сайт. Приложения, ориентированные на API уровня 16 или более ранние, особенно подвержены риску атаки, поскольку этот метод может использоваться для предоставления JavaScript возможности управлять хост-приложением. - Отображение ненадежного пользовательского контента в нативных WebView с поддержкой мостов позволяет осуществлять атаки межсайтового скриптинга (XSS).
- Метод
- Мосты на основе MessageChannel:
- Отсутствие проверок источника на конечных точках каналов обмена сообщениями означает, что сообщения будут приниматься от любого отправителя, включая сообщения, содержащие вредоносный код.
- Существует вероятность того, что Java может быть случайно доступна для произвольного JavaScript-кода.
Влияние
Методы addJavascriptInterface , postWebMessage и postMessage могут быть использованы злоумышленниками для доступа, манипулирования или внедрения контролируемого ими кода в WebView. Это может привести к перенаправлению пользователей на вредоносные сайты, загрузке вредоносного контента или запуску вредоносного кода на их устройствах, который может извлекать конфиденциальные данные или повышать привилегии.
Риск: риски, связанные с addJavascriptInterface
WebView реализует основные функции браузера, такие как отрисовка страниц, навигация и выполнение JavaScript. WebView можно использовать внутри приложения для отображения веб-контента в составе макета активности. Реализация нативного моста внутри WebView с использованием метода addJavascriptInterface может создавать проблемы безопасности, такие как межсайтовый скриптинг (XSS), или позволять злоумышленникам загружать ненадежный контент посредством внедрения интерфейса и манипулировать хост-приложением непредусмотренным образом, выполняя Java-код с правами хост-приложения.
Меры по смягчению последствий
Отключить JavaScript
В сценариях, когда WebView не требует JavaScript, не вызывайте метод setJavaScriptEnabled в WebSettings (например, при отображении статического HTML-контента). По умолчанию выполнение JavaScript в WebView отключено.
Удалять интерфейс JavaScript при загрузке ненадежного контента
Убедитесь, что объекты из JavaScript-интерфейса удалены, вызвав метод removeJavascriptInterface перед загрузкой ненадежного контента в WebView. Например, это можно сделать в вызове метода shouldInterceptRequest .
Котлин
webView.removeJavascriptInterface("myObject")
Java
webView.removeJavascriptInterface("myObject");
Загружайте веб-контент только по протоколу HTTPS.
Если вам необходимо загрузить ненадежный контент, убедитесь, что WebView загружает веб-контент через зашифрованное соединение (см. также наши рекомендации по передаче данных без шифрования ). Предотвратите первоначальную загрузку страницы через незашифрованные соединения, установив параметр android:usesCleartextTraffic в значение false в файле AndroidManifest или запретив HTTP-трафик в конфигурации сетевой безопасности . Дополнительную информацию см. в документации usesCleartextTraffic .
XML
<application
android:usesCleartextTraffic="false">
<!-- Other application elements -->
</application>
Чтобы предотвратить перенаправления и дальнейший просмотр веб-страниц приложения в незашифрованном трафике, проверьте схему HTTP в loadUrl или shouldInterceptRequest :
Котлин
fun loadSecureUrl(webView: WebView?, url: String?) {
webView?.let { wv -> // Ensure valid WebView and URL
url?.let {
try {
val uri = URI(url)
if (uri.scheme.equals("https", ignoreCase = true)) { // Enforce HTTPS scheme for security
wv.loadUrl(url)
} else {
// Log an error or handle the case where the URL is not secure
System.err.println("Attempted to load a non-HTTPS URL: $url")
}
} catch (e: Exception) {
// Handle exception for improper URL format
System.err.println("Invalid URL syntax: $url")
}
}
}
}
Java
public void loadSecureUrl(WebView webView, String url) {
if (webView != null && url != null) { // Ensure valid WebView and URL
try {
URI uri = new URI(url);
String scheme = uri.getScheme();
if ("https".equalsIgnoreCase(scheme)) { // Enforce HTTPS scheme for security
webView.loadUrl(url);
} else {
// Log an error or handle the case where the URL is not secure
System.err.println("Attempted to load a non-HTTPS URL: " + url);
}
} catch (URISyntaxException e) {
// Handle exception for improper URL format
System.err.println("Invalid URL syntax: " + url);
}
}
}
Проверьте достоверность ненадежного контента.
Если в WebView загружаются внешние ссылки, необходимо проверить схему и хост (домен из списка разрешенных). Домены, не включенные в список разрешенных, должны открываться браузером по умолчанию.
Не загружайте ненадежный контент.
По возможности загружайте в WebView только URL-адреса и контент, строго ограниченные областью видимости и принадлежащие разработчику приложения.
Не разглашайте конфиденциальные данные.
Если ваше приложение обращается к конфиденциальным данным через WebView, рассмотрите возможность использования метода clearCache для удаления всех файлов, хранящихся локально, перед использованием интерфейса JavaScript. Вы также можете использовать заголовки на стороне сервера, такие как no-store, чтобы указать, что приложение не должно кэшировать определенный контент.
Не раскрывайте конфиденциальные функции.
Если ваше приложение требует доступа к конфиденциальным данным или собирает конфиденциальную информацию, убедитесь, что оно вызывается из кода приложения и что пользователям предоставляется соответствующее уведомление. Избегайте использования интерфейсов JavaScript для любых конфиденциальных операций или работы с пользовательскими данными.
Целевой уровень API 21 или выше.
Один из безопасных способов использования метода addJavascriptInterface — это ориентация на API уровня 21 или выше, гарантируя, что метод вызывается только при работе с API уровня 21 или выше. До API 21 JavaScript мог использовать рефлексию для доступа к открытым полям внедренного объекта.
Риск: Риски, связанные с MessageChannel
Отсутствие контроля источника в postWebMessage() и postMessage() может позволить злоумышленникам перехватывать сообщения или отправлять сообщения собственным обработчикам.
Меры по смягчению последствий
При настройке postWebMessage() или postMessage() разрешайте только сообщения из доверенных доменов, избегая использования символа * в качестве целевого источника, и вместо этого явно указывайте ожидаемый домен отправителя.
Ресурсы
- Рекомендации по использованию функции postMessage()
- документация addJavascriptInterface
- документация по функции postMessage()
- Документация WebMessagePort.postMessage()
- Документация WebViewClient.shouldInterceptRequest
- Документация с рекомендациями по безопасности относительно addJavascriptInterface.
- документация clearCache
- удалить документацию JavaScript
- Включение JavaScript в WebViews