关于 CVE-2026-26897 的公开公告与 PoC — EcoOnline EHS Android(com.airsweb.v10)中的深度链接绕过,已在 0.2.500 版本中修复
CVE-2026-26897 的公开披露/公告,该漏洞是 EcoOnline EHS Android 应用 (com.airsweb.v10) 中的一个深度链接验证绕过。精心构造的 ehs-app:// 深度链接会被重写为 https:// 并直接加载到应用的主 WebView 中,绕过了应用在其他导航路径上都会执行的主机白名单检查,从而允许远程攻击者在受信任的应用内呈现任意攻击者控制的内容(钓鱼攻击)。
已负责任地披露,供应商已确认,并已在 0.2.500 版本中修复。
com.airsweb.v10 0.2.499 (版本代码 44631)供应商的应用是专有的,未在此仓库中重新分发。以下静态分析是在这里标识的构建版本上进行的 — 请从存档(例如 APKPure 版本历史)中获取确切的 APK,并在复现前验证其哈希值:
| 包名 | com.airsweb.v10 |
| 版本名称/版本代码 | 0.2.499 / 44631 |
| SHA-256 | e9e8a38d133cb9da9901caf03c4a7a033c75ad1f32ba0539260e47d5dd5068c0 |
EcoOnline EHS for Android 是一个围绕 EHS 网络平台的 Jetpack-Compose WebView 包装器。其默认内容从以下位置加载:
startUrl = "https://ehsmobilelanding.ecoonline.net/"
该应用导出单个 Activity (MainActivity),它既是启动器,也是自定义 URL scheme ehs-app 的处理程序。深度链接 intent-filter 的 <data> 元素仅声明了 scheme — 没有主机和路径 — 因此任何 ehs-app://… URI 都会被路由到该应用。
为了保护 WebView 导航,应用实现了一个主机白名单 (isInternalHost),并在恢复上次访问的 URL 时应用它。然而,深度链接处理分支根本没有调用该白名单。 它接受传入的深度链接 URI,执行简单的 scheme 字符串替换 ehs-app: → https:,然后对结果调用 WebView.loadUrl()。因此,远程攻击者可以构造一个深度链接,导致受信任的应用加载任意的 https:// 源。
AndroidManifest.xml (v0.2.499) — 导出的、仅 scheme 的深度链接<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 中的深度链接分支(反编译,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
}
}
该路径未能应用的白名单(在同一个文件的其他地方使用):
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);
}
次要说明:
internalDomains正则表达式本身较弱(损坏的交替 +containsMatchIn子字符串匹配),但主要问题是深度链接分支从未调用isInternalHost。
于 2026-01-13 针对 com.airsweb.v10 0.2.499 生成了屏幕录制 PoC。
ehs-app://attacker.example/login
MainActivity 重写 scheme,WebView 加载:
https://attacker.example/login
重定向的良性、非窃取性演示包含在 poc/redirect-proof.html(使用方法:poc/README.md)。它证明了任意源被加载到受信任的应用内,没有输入,没有凭据捕获,也没有网络请求。
在原始 PoC 中,研究人员托管了一个良性类似登录页面纯粹是为了演示重定向。本公告记录该漏洞是出于防御/披露目的,并且有意不包含钓鱼页面或凭据窃取代码。
https:// 内容。CVSS v3.1(研究人员估计 — 发布前确定):
AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N → 6.3(中危)(可以提出范围已更改的论点,因为不受信任的内容在受信任的应用上下文中执行)。
更新到 com.airsweb.v10 0.2.500 或更高版本。建议的修复:
loadUrl() 之前对深度链接 URL 应用 isInternalHost()(或等效的白名单)。android:host/android:pathPrefix 约束深度链接 intent-filter。internalDomains 正则表达式(完全锚定主机;避免子字符串匹配)。由 Ahmet Mersin 发现并报告 — GitHub @iwallplace,HackerOne iwallplace。
| 来源 | APKPure — "EcoOnline EHS" 版本历史 |
| 字段 | 值 |
|---|
| CVE ID | CVE-2026-26897 |
| 供应商 | EcoOnline ("EcoOnline Global") — https://www.ecoonline.com/ |
| 产品 | EcoOnline EHS for Android (com.airsweb.v10) |
| 受影响版本 | 0.2.499 (版本代码 44631) |
| 修复版本 | 0.2.500 |
| 漏洞类型 | 自定义 URL scheme 处理程序中的不当验证(深度链接绕过)→ 未经验证的 WebView 加载/开放重定向 |
| CWE | CWE-939 (自定义 URL Scheme 处理程序中的授权不当); 相关 CWE-749 |
| 受影响组件 | com.airsweb.v10.MainActivity (导出的深度链接处理程序) 和 MainActivityKt.WebViewPage 中的深度链接分支 |
| 自定义 scheme | ehs-app:// |
| 攻击类型 | 远程(需要用户交互 — 打开精心构造的链接) |
| 影响 | 钓鱼攻击/社会工程:在受信任的 EcoOnline EHS 应用内呈现任意攻击者控制的网页内容(例如伪造的登录页面),绕过应用的域名白名单 |
| 发现者 | Ahmet Mersin |
| 日期 | 事件 |
|---|
| 2026-01-13 | 针对 0.2.499 记录 PoC |
| 2026-01-15 | 向 MITRE 提交 CVE 请求 (工单 scr1979357) |
| 2026-02-27 | MITRE 分配 CVE-2026-26897 |
| 发布前 | 供应商确认;在 0.2.500 中发布修复 |
| 2026-03-04 | 向 MITRE 发送发布请求 |
| 2026-05-06 | MITRE 要求提供完整的公开披露 URL |
| 2026-06-03 | 公开公告发布(此仓库) |