
Advertencia pública y PoC para CVE-2026-26897 — Omisión de enlace profundo en EcoOnline EHS Android (com.airsweb.v10), corregido en 0.2.500
Divulgación pública / aviso para CVE-2026-26897, un bypass de validación de enlace profundo en la aplicación Android EcoOnline EHS (com.airsweb.v10). Un enlace profundo ehs-app:// manipulado se reescribe a https:// y se carga directamente en el WebView principal de la aplicación sin la comprobación de la lista blanca de hosts que la aplicación aplica en cualquier otra ruta de navegación, permitiendo que un atacante remoto renderice contenido arbitrario controlado por el atacante dentro de la aplicación de confianza (phishing).
Divulgado responsablemente, reconocido por el proveedor y corregido en la versión 0.2.500.
com.airsweb.v10 0.2.499 (versionCode 44631)La aplicación del proveedor es propietaria y no se redistribuye en este repositorio. El análisis estático a continuación se realizó en la compilación identificada aquí: obtenga el APK exacto de un archivo (por ejemplo, historial de versiones de APKPure) y verifique su hash antes de reproducir:
| Paquete | com.airsweb.v10 |
| versionName / versionCode | 0.2.499 / 44631 |
| SHA-256 | e9e8a38d133cb9da9901caf03c4a7a033c75ad1f32ba0539260e47d5dd5068c0 |
| Fuente | APKPure — historial de versiones de "EcoOnline EHS" |
| Campo | Valor |
|---|---|
| CVE ID | CVE-2026-26897 |
| Proveedor | EcoOnline ("EcoOnline Global") — https://www.ecoonline.com/ |
| Producto | EcoOnline EHS para Android (com.airsweb.v10) |
| Versión afectada | 0.2.499 (versionCode 44631) |
| Versión corregida | 0.2.500 |
| Tipo de vulnerabilidad | Validación incorrecta en un manejador de esquema de URL personalizado (bypass de enlace profundo) → carga de WebView no validada / redirección abierta |
| CWE | CWE-939 (Autorización incorrecta en el manejador de esquema de URL personalizado); relacionado CWE-749 |
| Componente afectado | com.airsweb.v10.MainActivity (manejador de enlace profundo exportado) y la rama de enlace profundo en MainActivityKt.WebViewPage |
| Esquema personalizado | ehs-app:// |
| Tipo de ataque | Remoto (requiere interacción del usuario — abrir un enlace manipulado) |
| Impacto | Phishing / ingeniería social: contenido web arbitrario controlado por el atacante renderizado dentro de la aplicación EcoOnline EHS de confianza (por ejemplo, un inicio de sesión falso), evitando la lista blanca de dominios de la aplicación |
| Descubridor | Ahmet Mersin |
EcoOnline EHS para Android es un envoltorio WebView de Jetpack-Compose alrededor de la plataforma web EHS. Su contenido predeterminado se carga desde:
startUrl = "https://ehsmobilelanding.ecoonline.net/"
La aplicación exporta una sola Activity (MainActivity) que es tanto el lanzador como el manejador del esquema de URL personalizado ehs-app. El elemento <data> del intent-filter de enlace profundo declara solo un esquema — sin host y sin ruta — por lo que cualquier URI ehs-app://… se enruta a la aplicación.
Para proteger la navegación del WebView, la aplicación implementa una lista blanca de hosts (isInternalHost) y la aplica al restaurar la última URL visitada. Sin embargo, la rama de manejo de enlaces profundos no llama a esa lista blanca en absoluto. Toma la URI del enlace profundo entrante, realiza un reemplazo de cadena ingenuo del esquema ehs-app: → https:, y llama a WebView.loadUrl() en el resultado. Por lo tanto, un atacante remoto puede crear un enlace profundo que haga que la aplicación de confianza cargue un origen https:// arbitrario.
AndroidManifest.xml (v0.2.499) — enlace profundo exportado, solo 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"/> <!-- scheme only: no host, no path -->
</intent-filter>
</activity>
MainActivityKt.WebViewPage (descompilado, v0.2.499)// intent delivered to the exported MainActivity
if (intent.getScheme().equals("ehs-app")) {
WebView webView = ...;
if (webView != null) {
Uri data = intent.getData(); // full ehs-app://… URI
String s = String.valueOf(data);
// naïve scheme rewrite: "ehs-app:" -> "https:"
String url = StringsKt.replaceFirst(s, "ehs-app:", "https:", false, 4, null);
webView.loadUrl(url); // <-- NO isInternalHost() CHECK
}
}
La lista blanca que esta ruta no aplica (usada en otro lugar del mismo archivo):
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 secundaria: la expresión regular
internalDomainses en sí misma débil (alternancia rota + coincidencia de subcadenascontainsMatchIn), pero el problema principal es que la rama de enlace profundo nunca invocaisInternalHosten absoluto.
Se produjo una PoC de grabación de pantalla el 2026-01-13 contra com.airsweb.v10 0.2.499.
ehs-app://attacker.example/login
MainActivity reescribe el esquema y el WebView carga:
https://attacker.example/login
dentro de la aplicación EcoOnline EHS de confianza — no se realiza ninguna comprobación de la lista blanca.Se incluye una demostración benigna, no recolectora de la redirección en poc/redirect-proof.html (uso: poc/README.md). Prueba que se carga un origen arbitrario dentro de la aplicación de confianza, sin entradas, sin captura de credenciales y sin solicitudes de red.
En la PoC original, el investigador alojó una página de destino similar benigna únicamente para demostrar la redirección. Este aviso documenta la vulnerabilidad con fines defensivos/de divulgación y contiene intencionalmente ninguna página de phishing ni código de captura de credenciales.