
Advertência pública e PoC para CVE-2026-26897 — Bypass de Deep Link no EcoOnline EHS Android (com.airsweb.v10), corrigido na versão 0.2.500
Divulgação pública / aviso para CVE-2026-26897, um bypass de validação de deep link no aplicativo Android EcoOnline EHS (com.airsweb.v10). Um deep link malicioso ehs-app:// é reescrito para https:// e carregado diretamente no WebView principal do aplicativo sem a verificação da lista de permissões de host que o aplicativo aplica em todos os outros caminhos de navegação, permitindo que um atacante remoto renderize conteúdo arbitrário controlado pelo atacante dentro do aplicativo confiável (phishing).
Divulgado de forma responsável, reconhecido pelo fornecedor e corrigido na versão 0.2.500.
com.airsweb.v10 0.2.499 (versionCode 44631)O aplicativo do fornecedor é proprietário e não é redistribuído neste repositório. A análise estática abaixo foi realizada na compilação identificada aqui — obtenha o APK exato de um arquivo (ex.: histórico de versões do APKPure) e verifique seu hash antes de reproduzir:
| Pacote | com.airsweb.v10 |
| versionName / versionCode | 0.2.499 / 44631 |
O EcoOnline EHS para Android é um wrapper WebView Jetpack-Compose em torno da plataforma web EHS. Seu conteúdo padrão é carregado de:
startUrl = "https://ehsmobilelanding.ecoonline.net/"
O aplicativo exporta uma única Activity (MainActivity) que é tanto o lançador quanto o manipulador para o esquema de URL personalizado ehs-app. O elemento <data> do intent-filter de deep link declara apenas um esquema — sem host e sem caminho — então qualquer URI ehs-app://… é roteada para o aplicativo.
Para proteger a navegação do WebView, o aplicativo implementa uma lista de permissões de host (isInternalHost) e a aplica ao restaurar o último URL visitado. No entanto, o ramo de manipulação de deep link não chama essa lista de permissões. Ele pega a URI de deep link recebida, realiza uma substituição ingênua de string do esquema ehs-app: → https: e chama WebView.loadUrl() no resultado. Um atacante remoto pode, portanto, criar um deep link que faz com que o aplicativo confiável carregue uma origem https:// arbitrária.
AndroidManifest.xml (v0.2.499) — deep link exportado, apenas esquema<activity
android:name="com.airsweb.v10.MainActivity"
android:exported="true" ... >
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<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="ehs-app"/> <!-- apenas esquema: sem host, sem caminho -->
</intent-filter>
</activity>
MainActivityKt.WebViewPage (decompilado, v0.2.499)// intent entregue à MainActivity exportada
if (intent.getScheme().equals("ehs-app")) {
WebView webView = ...;
if (webView != null) {
Uri data = intent.getData(); // URI completa ehs-app://…
String s = String.valueOf(data);
// reescrita ingênua de esquema: "ehs-app:" -> "https:"
String url = StringsKt.replaceFirst(s, "ehs-app:", "https:", false, 4, null);
webView.loadUrl(url); // <-- SEM verificação isInternalHost()
}
}
A lista de permissões que este caminho deixa de aplicar (usada em outro lugar no mesmo arquivo):
private static final Regex internalDomains =
new Regex("^[-\\w]*\\.(airsweb)|(ecoonline)\\.net");
private static final List<String> excludeDomainsStartingWith =
listOf("passport", "login", "auth");
public static boolean isInternalHost(String host) {
for (String p : excludeDomainsStartingWith)
if (host.startsWith(p)) return false;
return internalDomains.containsMatchIn(host);
}
Nota secundária: a regex
internalDomainsé em si fraca (alternância quebrada + correspondência de substringcontainsMatchIn), mas o problema principal é que o ramo de deep link nunca invocaisInternalHost.
Uma gravação de tela PoC foi produzida em 2026-01-13 contra com.airsweb.v10 0.2.499.
ehs-app://attacker.example/login
MainActivity reescreve o esquema e o WebView carrega:
https://attacker.example/login
Uma demonstração benigna, sem captura do redirecionamento está incluída em poc/redirect-proof.html (uso: poc/README.md). Ela prova que uma origem arbitrária é carregada dentro do aplicativo confiável, sem entradas, sem captura de credenciais e sem requisições de rede.
No PoC original, o pesquisador hospedou uma página de destino semelhante benigna apenas para demonstrar o redirecionamento. Este aviso documenta a vulnerabilidade para fins defensivos / de divulgação e intencionalmente não contém nenhuma página de phishing ou código de captura de credenciais.
https:// arbitrário controlado pelo atacante dentro do contexto do aplicativo confiável.CVSS v3.1 (estimativa do pesquisador — finalizar antes da publicação):
AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N → 6.3 (Médio) (um argumento de Escopo: Alterado pode ser feito, já que conteúdo não confiável é executado no contexto do aplicativo confiável).
Atualize para com.airsweb.v10 0.2.500 ou posterior. Correções recomendadas:
isInternalHost() (ou uma lista de permissões equivalente) aos URLs de deep link antes de loadUrl().intent-filter de deep link com um android:host/android:pathPrefix explícito.internalDomains (ancore completamente o host; evite correspondências de substring).Descoberto e reportado por Ahmet Mersin — GitHub @iwallplace, HackerOne iwallplace.
| SHA-256 |
e9e8a38d133cb9da9901caf03c4a7a033c75ad1f32ba0539260e47d5dd5068c0 |
| Fonte | APKPure — histórico de versões "EcoOnline EHS" |
| Campo | Valor |
|---|
| ID do CVE | CVE-2026-26897 |
| Fornecedor | EcoOnline ("EcoOnline Global") — https://www.ecoonline.com/ |
| Produto | EcoOnline EHS para Android (com.airsweb.v10) |
| Versão afetada | 0.2.499 (versionCode 44631) |
| Versão corrigida | 0.2.500 |
| Tipo de vulnerabilidade | Validação inadequada em um manipulador de esquema de URL personalizado (bypass de deep link) → carga de WebView não validada / open redirect |
| CWE | CWE-939 (Autorização inadequada no manipulador de esquema de URL personalizado); relacionado CWE-749 |
| Componente afetado | com.airsweb.v10.MainActivity (manipulador de deep link exportado) e o ramo de deep link em MainActivityKt.WebViewPage |
| Esquema personalizado | ehs-app:// |
| Tipo de ataque | Remoto (requer interação do utilizador — abrir um link malicioso) |
| Impacto | Phishing / engenharia social: conteúdo web arbitrário controlado pelo atacante renderizado dentro do aplicativo confiável EcoOnline EHS (ex.: um login falso), ignorando a lista de permissões de domínio do aplicativo |
| Descobridor | Ahmet Mersin |
| Data | Evento |
|---|
| 2026-01-13 | PoC gravado contra 0.2.499 |
| 2026-01-15 | Pedido de CVE submetido à MITRE (ticket scr1979357) |
| 2026-02-27 | CVE-2026-26897 atribuído pela MITRE |
| antes da publicação | Fornecedor reconheceu; correção lançada em 0.2.500 |
| 2026-03-04 | Pedido de publicação enviado à MITRE |
| 2026-05-06 | MITRE solicitou um URL de divulgação pública completo |
| 2026-06-03 | Aviso público publicado (este repositório) |