WebView – собственные мосты

Категория OWASP: MASVS-ПЛАТФОРМА: Взаимодействие платформы

Обзор

Собственный мост, иногда называемый мостом JavaScript, — это механизм, который облегчает связь между WebView и собственным кодом Android, достигаемый с помощью метода addJavascriptInterface . Это обеспечивает двустороннюю связь между кодом JavaScript, выполняемым в WebView, и кодом Java приложения Android. Метод addJavascriptInterface предоставляет объект Java всем фреймам WebView, и любой фрейм может получить доступ к имени объекта и вызвать его методы. Однако приложение не имеет механизма проверки происхождения вызывающего кадра внутри WebView, что вызывает проблемы безопасности, поскольку достоверность содержимого остается неопределенной.

Собственный мост также можно реализовать с помощью каналов сообщений 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 управлять хост-приложением.
    • Отражение ненадежного пользовательского контента в собственных WebViews с поддержкой моста позволяет проводить атаки с использованием межсайтовых сценариев (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")

Ява

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

Ява

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 мог использовать отражение для доступа к общедоступным полям внедренного объекта.


Риск: риски канала сообщений

Отсутствие контроля происхождения в postWebMessage() и postMessage() может позволить злоумышленникам перехватывать сообщения или отправлять сообщения собственным обработчикам.

Смягчения

При настройке postWebMessage() или postMessage() разрешайте сообщения только из доверенных доменов, избегая использования * в качестве целевого источника и вместо этого явно указывая ожидаемый домен отправки.


Ресурсы