FlawOpen

flawopen.com/Segurança do WebView no Android/addJavascriptInterface

Android addJavascriptInterface: riscos e uso seguro

Página de referência
Resposta curta

Trate um WebView com addJavascriptInterface como uma fronteira privilegiada. O Android injeta o objeto em todos os frames e o app não consegue identificar qual frame chamou o método. Se JavaScript controlado por um atacante alcançar qualquer frame, ele poderá chamar métodos expostos com as permissões do app. Reserve WebViews com bridge para conteúdo controlado pelo app e carregue páginas não confiáveis em outro WebView sem a bridge.

Como a bridge muda o impacto de XSS

Uma bridge dá ao JavaScript pontos de entrada chamáveis no app hospedeiro. O Android expõe o objeto a todos os frames, inclusive iframes, e addJavascriptInterface não verifica a origem do frame chamador. Um script injetado pode alcançar métodos anotados; o que consegue fazer depende desses métodos e das verificações de autorização do app. Em apps com API de destino 16 ou anterior, o Android documenta um comportamento legado mais grave: todos os métodos públicos podem ficar expostos. A partir da API 17, @JavascriptInterface é exigido, mas a anotação não torna conteúdo não confiável seguro.

Mantenha a bridge longe de páginas não confiáveis

ARRISCADO — bridge e navegação não confiável no mesmo WebView
webView.addJavascriptInterface(
  NativeBridge(), "Android"
)
webView.loadUrl(untrustedUrl)
MAIS SEGURO — separar conteúdo confiável e não confiável
// Este WebView é reservado à interface empacotada e controlada pelo app.
trustedWebView.settings.javaScriptEnabled = true
trustedWebView.addJavascriptInterface(
  NativeBridge(), "Android"
)
trustedWebView.loadUrl("file:///android_asset/index.html")

// Outro WebView trata páginas remotas ou controladas por usuários.
untrustedWebView.removeJavascriptInterface("Android")
untrustedWebView.settings.javaScriptEnabled = false
// Valide HTTPS e uma allowlist explícita de hosts.
untrustedWebView.loadUrl(validatedHttpsUrl)

A fronteira mais forte é arquitetural: nunca navegue com um WebView que tenha bridge para uma página remota, criada por usuário ou influenciada por um atacante. Se for inevitável carregar conteúdo não confiável, remova a interface antes do carregamento e use outro WebView com JavaScript desativado, salvo se for necessário. O Android informa que o objeto injetado fica disponível a todos os frames e que a remoção só produz efeito após o próximo carregamento. HTTPS protege o transporte; não torna um host ou seu conteúdo confiável. Valide o esquema e o host da URL e abra links fora da allowlist no navegador do sistema. Restrinja os métodos da bridge, valide cada argumento e aplique autorização no código nativo, sem confiar na página chamadora.

Perguntas frequentes sobre segurança da bridge do WebView

A API 17 ou superior torna addJavascriptInterface seguro?

Não. A API 17+ limita a exposição a métodos públicos anotados com @JavascriptInterface; ela não verifica a origem do frame chamador nem torna confiável conteúdo controlado por um atacante. Mantenha a bridge em um WebView que carregue somente conteúdo controlado pelo app.

Referências

Veja também Cross-Site Scripting (XSS, CWE-79): como funciona e como evitar em todas as linguagens — flawopen.com Proteção XSS do Angular: padrões seguros e APIs de bypass XSS por MIME sniffing: Content-Type e nosniff CSP e escape de saída: você precisa dos dois? dangerouslySetInnerHTML do React é seguro? DOMPurify basta para proteger innerHTML? Markdown é seguro contra XSS?