Categoria OWASP: MASVS-PLATFORM: Platform Interaction
Panoramica
Un bridge nativo, a volte noto come bridge JavaScript, è un meccanismo che
facilita la comunicazione tra un componente WebView e il codice Android nativo, ottenuto utilizzando il addJavascriptInterface metodo. Ciò consente la comunicazione bidirezionale tra il codice JavaScript in esecuzione nel componente WebView e il codice Java dell'applicazione Android. Il metodo addJavascriptInterface espone un oggetto Java a tutti i frame di un componente WebView e qualsiasi frame può accedere al nome dell'oggetto e chiamare i metodi su di esso. Tuttavia, non esiste un meccanismo per l'applicazione per verificare l'origine del frame chiamante all'interno del componente WebView, il che solleva problemi di sicurezza in quanto l'attendibilità dei contenuti rimane indeterminata.
Un bridge nativo può essere implementato anche con i canali di messaggi HTML utilizzando
WebViewCompat.postWebMessage di Android o
WebMessagePort.postMessage per comunicare con Window.postMessage di JavaScript. WebViewCompat.postWebMessage e WebMessagePort.postMessage possono accettare messaggi JavaScript inviati tramite Window.postMessage che verranno eseguiti all'interno del componente WebView.
Esistono diversi rischi associati ai bridge nativi:
- Bridge basati su JavascriptInterface:
- Il metodo
addJavascriptInterfaceinserisce un oggetto Java fornito in ogni frame del componente WebView, inclusi gli iframe, il che significa che è suscettibile di attacchi da parte di terze parti malintenzionate che inseriscono frame in un sito web legittimo. Le applicazioni che hanno come target il livello API 16 o precedente sono particolarmente a rischio di attacco perché questo metodo può essere utilizzato per consentire a JavaScript di controllare l'applicazione host. - La visualizzazione di contenuti non attendibili forniti dall'utente nei componenti WebView abilitati per il bridge nativo consente attacchi di tipo "cross-site scripting" (XSS).
- Il metodo
- Bridge basati su MessageChannel:
- La mancanza di controlli di origine sugli endpoint del canale di messaggi significa che i messaggi verranno accettati da qualsiasi mittente, inclusi quelli contenenti codice dannoso.
- È possibile esporre accidentalmente Java a JavaScript arbitrario.
Impatto
Gli attori malintenzionati possono sfruttare i metodi addJavascriptInterface, postWebMessage e postMessage per accedere, manipolare o inserire codice che controllano in un componente WebView. Ciò potrebbe comportare il reindirizzamento degli utenti a siti dannosi, il caricamento di contenuti dannosi o l'esecuzione di codice dannoso sui loro dispositivi in grado di estrarre dati sensibili o ottenere l'escalation dei privilegi.
Rischio: rischi di addJavascriptInterface
WebView implementa le funzionalità di base di un browser, come il rendering delle pagine, la navigazione e l'esecuzione di JavaScript. WebView può essere utilizzato all'interno di un'applicazione per visualizzare contenuti web come parte di un layout di attività. L'implementazione di un bridge nativo all'interno di un componente WebView utilizzando il metodo addJavascriptInterface può creare problemi di sicurezza come lo scripting cross-site (XSS) o consentire agli utenti malintenzionati di caricare contenuti non attendibili tramite l'inserimento dell'interfaccia e manipolare l'applicazione host in modi non previsti, eseguendo codice Java con le autorizzazioni dell'applicazione host.
Mitigazioni
Viene disattivato JavaScript
Negli scenari in cui WebView non richiede JavaScript, non chiamare
setJavaScriptEnabled all'interno di WebSettings (ad esempio, durante
la visualizzazione di contenuti HTML statici). Per impostazione predefinita, l'esecuzione di JavaScript è disattivata in WebView.
Rimuovi l'interfaccia JavaScript durante il caricamento di contenuti non attendibili
Assicurati che gli oggetti dell'interfaccia JavaScript vengano rimossi chiamando
removeJavascriptInterface prima che vengano caricati contenuti non attendibili dal
componente WebView. Ad esempio, questa operazione può essere eseguita in una chiamata a
shouldInterceptRequest.
Kotlin
webView.removeJavascriptInterface("myObject")
Java
webView.removeJavascriptInterface("myObject");
Carica solo contenuti web tramite HTTPS
Se devi caricare contenuti non attendibili, assicurati che il componente WebView carichi i contenuti web tramite
una connessione criptata (consulta anche le nostre linee guida sulle comunicazioni
in testo non criptato). Impedisci il caricamento iniziale della pagina su
connessioni non criptate impostando android:usesCleartextTraffic su false in
il file AndroidManifest o non consentire il traffico HTTP in una configurazione di sicurezza di
rete. Per ulteriori informazioni, consulta la documentazione di usesCleartextTraffic.
Xml
<application
android:usesCleartextTraffic="false">
<!-- Other application elements -->
</application>
Per assicurarti che i reindirizzamenti e l'ulteriore navigazione dell'app non avvengano su traffico non criptato, controlla lo schema HTTP in loadUrl o
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);
}
}
}
Convalida i contenuti non attendibili
Se in un componente WebView vengono caricati link esterni, convalida sia lo schema sia l'host (domini della lista consentita). I domini non inclusi nella lista consentita devono essere aperti dal browser predefinito.
Non caricare contenuti non attendibili
Se possibile, carica in WebView solo gli URL con ambito limitato e i contenuti di proprietà dello sviluppatore dell'app.
Non esporre dati sensibili
Se la tua applicazione accede a dati sensibili con un componente WebView, valuta la possibilità di utilizzare il
clearCache metodo per eliminare tutti i file archiviati localmente prima di utilizzare l'
interfaccia JavaScript. Puoi anche utilizzare le intestazioni lato server, ad esempio no-store, per indicare che un'applicazione non deve memorizzare nella cache contenuti specifici.
Non esporre funzionalità sensibili
Se la tua applicazione richiede autorizzazioni sensibili o raccoglie dati sensibili, assicurati che venga chiamata dal codice all'interno dell'applicazione e che agli utenti venga fornita una divulgazione ben visibile. Evita di utilizzare le interfacce JavaScript per operazioni sensibili o dati utente.
Effettua il targeting del livello API 21 o superiore
Un modo sicuro per utilizzare il metodo addJavascriptInterface è effettuare il targeting del livello API 21 o superiore assicurandosi che il metodo venga chiamato solo quando è in esecuzione sul livello API 21 o superiore. Prima dell'API 21, JavaScript poteva utilizzare la reflection per accedere ai campi pubblici di un oggetto inserito.
Rischio: rischi di MessageChannel
La mancanza di controllo dell'origine in postWebMessage() e postMessage() potrebbe consentire agli utenti malintenzionati di intercettare i messaggi o inviare messaggi ai gestori nativi.
Mitigazioni
Quando configuri postWebMessage() o postMessage(), consenti solo i messaggi provenienti da domini attendibili evitando l'uso di * come origine di destinazione e specificando invece esplicitamente il dominio di invio previsto.
Risorse
- Best practice per postMessage()
- Documentazione di addJavascriptInterface
- Documentazione di postMessage()
- Documentazione di WebMessagePort.postMessage()
- Documentazione di WebViewClient.shouldInterceptRequest
- Documentazione dei consigli di sicurezza relativi a addJavascriptInterface
- Documentazione di clearCache
- Documentazione di removeJavascript
- Abilitazione di JavaScript in WebView