Kategoria OWASP: MASVS-PLATFORM: Interakcja z platformą
Omówienie
Natywna usługa mostu, zwana też usługą mostu JavaScript, to mechanizm ułatwiający komunikację między WebView a natywnym kodem Androida. Aby go użyć, użyj metody addJavascriptInterface
. Umożliwia to dwukierunkową komunikację między kodem JavaScript działającym w komponencie WebView a kodem Java aplikacji na Androida. Metoda addJavascriptInterface
udostępnia środowisko Java
do wszystkich ramek WebView, a każda ramka ma dostęp do nazwy obiektu
i metod wywołania. Nie ma jednak mechanizmu, który pozwoliłby aplikacji zweryfikować pochodzenie wywołującej ramki w komponencie WebView. Powoduje to obawy dotyczące bezpieczeństwa, ponieważ nie można określić wiarygodności treści.
Most natywny można też zaimplementować za pomocą kanałów wiadomości HTML, używając WebViewCompat.postWebMessage
lub WebMessagePort.postMessage
na Androidzie do komunikacji z JavaScriptem Window.postMessage
. WebViewCompat.postWebMessage
i
WebMessagePort.postMessage
może akceptować wiadomości JavaScript wysyłane przez
Window.postMessage
, który zostanie uruchomiony w komponencie WebView.
Z użyciem mostów natywnych wiąże się kilka zagrożeń:
- Mostki oparte na JavascriptInterface:
- Metoda
addJavascriptInterface
wprowadza podany obiekt Java do każdej klatki komponentu WebView, w tym elementów iframe, co oznacza, że jest narażona na przez złośliwe osoby trzecie wstrzykujące ramki do wiarygodnej witryny. Aplikacje kierowane na interfejs API na poziomie 16 lub wyższym są szczególnie narażone na atak, ponieważ można użyć tej metody, aby umożliwić JavaScriptowi kontrolowanie hosta aplikacji. - Odzwierciedlenie niezaufanych treści przekazywanych przez użytkowników w natywnych komponentach WebView obsługujących mosty umożliwia ataki typu cross-site scripting (XSS).
- Metoda
- Mosty oparte na MessageChannel:
- Brak weryfikacji pochodzenia na punktach końcowych kanału wiadomości oznacza, że wiadomości będą akceptowane od dowolnego nadawcy, w tym tych zawierających złośliwy kod.
- Istnieje ryzyko przypadkowego ujawnienia Javy dla dowolnego JavaScriptu.
Wpływ
Metody addJavascriptInterface
, postWebMessage
i postMessage
mogą być
wykorzystywane przez złośliwe podmioty w celu uzyskania dostępu do kontrolowanego przez siebie kodu, manipulowania nim lub wstrzykiwania
w komponencie WebView. Może to prowadzić do przekierowywania użytkowników do szkodliwych witryn, wczytywania szkodliwych treści lub uruchamiania na urządzeniach szkodliwego kodu, który może wydobyć dane poufne lub uzyskać dostęp do uprawnień.
Zagrożenie: zagrożenia związane z metodą addJavascriptInterface
WebView implementuje podstawowe funkcje przeglądarki, takie jak renderowanie stron,
nawigacji i wykonania JavaScriptu. Komponent WebView można używać w aplikacji
wyświetlanie treści z internetu w ramach układu aktywności. Wdrażanie reklam natywnych
mostu w komponencie WebView przy użyciu metody addJavascriptInterface
może tworzyć
problemy z bezpieczeństwem, np. ataki typu cross-site scripting (XSS), lub które umożliwiają hakerom wczytanie
niezaufanych treści poprzez wstrzykiwanie kodu do interfejsu i manipulowanie hostem
niezamierzonego uruchomienia kodu w Javie z użyciem uprawnień
aplikacji hosta.
Łagodzenie
Wyłącz JavaScript
W sytuacjach, gdy komponent WebView nie wymaga JavaScriptu, nie wywołuj metody setJavaScriptEnabled
w komponencie WebSettings
(np. podczas wyświetlania statycznych treści HTML). Domyślnie wykonywanie kodu JavaScript jest wyłączone w WebView.
Usuń interfejs JavaScript podczas wczytywania niezaufanych treści
Przed wczytaniem niezaufanych treści przez komponent WebView usuń obiekty z interfejsu JavaScript, wywołując metodę removeJavascriptInterface
. Można to zrobić na przykład w wywołaniu funkcji
shouldInterceptRequest
Kotlin
webView.removeJavascriptInterface("myObject")
Java
webView.removeJavascriptInterface("myObject");
Ładuj treści internetowe tylko przez HTTPS
Jeśli chcesz wczytać niezaufane treści, upewnij się, że komponent WebView wczytuje treści z internetu:
połączenia zaszyfrowanego (przeczytaj też nasze wytyczne na temat Cleartext
Komunikacja). Nie zezwalaj na początkowe wczytywanie strony
niezaszyfrowane połączenia przez ustawienie android:usesCleartextTraffic
na false
w
AndroidManifest
lub nie zezwalaj na ruch HTTP z zastosowaniem zabezpieczeń sieciowych
config. Więcej informacji znajdziesz w dokumentacji usesCleartextTraffic
.
XML
<application
android:usesCleartextTraffic="false">
<!-- Other application elements -->
</application>
Aby mieć pewność, że w przypadku niezaszyfrowanego przekierowania nie będą występować przekierowania i dalsze przeglądanie aplikacji
ruchu, sprawdź schemat HTTP w loadUrl
lub
shouldInterceptRequest
:
Kotlin
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);
}
}
}
Sprawdzanie niesprawdzonych treści
Jeśli jakieś linki zewnętrzne są wczytane w komponencie WebView, zweryfikuj zarówno schemat, jak i hosta (domeny z listy dozwolonych). Domeny, które nie znajdują się na liście dozwolonych, powinny być otwierane przez domyślną przeglądarkę.
Nie wczytuj niesprawdzonych treści
W miarę możliwości wczytuj w komponencie WebView tylko adresy URL o ściśle określonym zakresie oraz treści należące do dewelopera aplikacji.
Nie udostępniaj danych wrażliwych
Jeśli Twoja aplikacja uzyskuje dostęp do danych wrażliwych za pomocą komponentu WebView, zastosuj
clearCache
, by usunąć pliki przechowywane lokalnie, zanim użyjesz
Interfejs JavaScript. Możesz też używać nagłówków po stronie serwera, takich jak no-store, aby wskazać, że aplikacja nie powinna przechowywać w pamięci podręcznej określonych treści.
Nie ujawniaj poufnych funkcji
Jeśli aplikacja wymaga uprawnień newralgicznych lub zbiera dane poufne, musisz zadbać o to, aby były wywoływane z kodu w aplikacji, oraz o to, aby użytkownicy byli wyraźnie informowani o ich dostępie do tych danych. Unikaj używania interfejsów JavaScript do wykonywania operacji na danych poufnych lub danych użytkownika.
Docelowy poziom interfejsu API 21 lub wyższy
Jednym ze sposobów bezpiecznego korzystania z metody addJavascriptInterface
jest kierowanie na poziom interfejsu API 21 lub wyższy. Aby to zrobić, zadbaj o to, aby metoda była wywoływana tylko wtedy, gdy działa na poziomie interfejsu API 21 lub wyższym. Przed wersją 21 interfejsu API kod JavaScript mógł używać odbicia do uzyskiwania dostępu do publicznych pól wstrzykniętego obiektu.
Ryzyko: ryzyko związane z kanałem wiadomości
Brak kontroli pochodzenia w funkcjach postWebMessage()
i postMessage()
może umożliwiać atakującym przechwytywanie wiadomości lub wysyłanie ich do natywnych modułów obsługi.
Łagodzenie
Podczas konfigurowania postWebMessage()
lub postMessage()
zezwalaj tylko na wiadomości z zaufanych domen, unikając użycia * jako docelowego źródła. Zamiast tego wyraźnie określ oczekiwaną domenę nadawcy.
Materiały
- Sprawdzone metody postMessage()
- Dokumentacja addJavascriptInterface
- Dokumentacja postMessage()
- Dokumentacja WebMessagePort.postMessage()
- Dokumentacja WebViewClient.shouldInterceptRequest
- Dokumentacja z informacjami dotyczącymi bezpieczeństwa metody addJavascriptInterface
- dokumentacja czyszczenia pamięci podręcznej
- DokumentacjaremoveJavascript
- włączanie JavaScriptu w komponentach WebView