
CVE-2026-26897 के लिए सार्वजनिक एडवाइज़री और PoC — EcoOnline EHS Android (com.airsweb.v10) में Deep Link Bypass, 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 (versionCode 44631)विक्रेता का एप्लिकेशन मालिकाना है और इस रिपॉजिटरी में पुनर्वितरित नहीं किया गया है। नीचे दिया गया स्थैतिक विश्लेषण यहाँ पहचाने गए बिल्ड पर किया गया था — पुनरुत्पादन से पहले किसी संग्रह (जैसे APKPure संस्करण इतिहास) से सटीक APK प्राप्त करें और उसका हैश सत्यापित करें:
| पैकेज | com.airsweb.v10 |
| versionName / versionCode | 0.2.499 / 44631 |
EcoOnline EHS एंड्रॉइड के लिए EHS वेब प्लेटफ़ॉर्म के चारों ओर एक Jetpack-Compose WebView रैपर है। इसकी डिफ़ॉल्ट सामग्री इससे लोड होती है:
startUrl = "https://ehsmobilelanding.ecoonline.net/"
ऐप एक एकल Activity (MainActivity) निर्यात करता है जो लॉन्चर और कस्टम URL स्कीम ehs-app के लिए हैंडलर दोनों है। डीप-लिंक intent-filter का <data> तत्व केवल एक स्कीम घोषित करता है — कोई होस्ट और कोई पथ नहीं — इसलिए कोई भी ehs-app://… URI ऐप पर रूट किया जाता है।
WebView नेविगेशन की सुरक्षा के लिए, ऐप एक होस्ट अनुमति-सूची (isInternalHost) लागू करता है और इसे अंतिम-देखी गई URL को पुनर्स्थापित करते समय लागू करता है। हालाँकि, डीप-लिंक हैंडलिंग शाखा उस अनुमति-सूची को बिल्कुल नहीं बुलाती है। यह आने वाले डीप-लिंक URI को लेती है, स्कीम ehs-app: → https: का एक भोला स्ट्रिंग प्रतिस्थापन करती है, और परिणाम पर WebView.loadUrl() को कॉल करती है। इसलिए एक दूरस्थ हमलावर एक डीप लिंक बना सकता है जो विश्वसनीय ऐप को एक मनमाना https:// ओरिजिन लोड करने के लिए प्रेरित करता है।
AndroidManifest.xml (v0.2.499) — निर्यातित, केवल-स्कीम डीप लिंक<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);
}
द्वितीयक टिप्पणी:
internalDomainsregex स्वयं कमजोर है (टूटा हुआ विकल्प +containsMatchInसबस्ट्रिंग मिलान), लेकिन प्राथमिक मुद्दा यह है कि डीप-लिंक शाखा कभी भीisInternalHostको बिल्कुल कॉल नहीं करती है।
com.airsweb.v10 0.2.499 के विरुद्ध 2026-01-13 को एक स्क्रीन-रिकॉर्डिंग PoC तैयार की गई थी।
ehs-app://attacker.example/login
MainActivity स्कीम को पुनर्लिखित करता है और 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 (मध्यम) (एक Scope:Changed तर्क दिया जा सकता है, क्योंकि
अविश्वसनीय सामग्री विश्वसनीय ऐप संदर्भ में निष्पादित होती है)।
com.airsweb.v10 0.2.500 या बाद के संस्करण में अपडेट करें। अनुशंसित सुधार:
loadUrl() से पहले isInternalHost() (या एक समकक्ष अनुमति-सूची) लागू करें।intent-filter को एक स्पष्ट android:host/android:pathPrefix के साथ सीमित करें।internalDomains regex को मजबूत करें (होस्ट को पूरी तरह से एंकर करें; सबस्ट्रिंग मिलान से बचें)।Ahmet Mersin द्वारा खोजा और रिपोर्ट किया गया — GitHub @iwallplace, HackerOne iwallplace।
| SHA-256 |
e9e8a38d133cb9da9901caf03c4a7a033c75ad1f32ba0539260e47d5dd5068c0 |
| स्रोत | APKPure — "EcoOnline EHS" संस्करण इतिहास |
| फ़ील्ड | मान |
|---|
| CVE ID | CVE-2026-26897 |
| विक्रेता | EcoOnline ("EcoOnline Global") — https://www.ecoonline.com/ |
| उत्पाद | EcoOnline EHS एंड्रॉइड के लिए (com.airsweb.v10) |
| प्रभावित संस्करण | 0.2.499 (versionCode 44631) |
| ठीक किया गया संस्करण | 0.2.500 |
| कमजोरी का प्रकार | कस्टम URL स्कीम हैंडलर में अनुचित सत्यापन (डीप लिंक बायपास) → असत्यापित WebView लोड / ओपन रीडायरेक्ट |
| CWE | CWE-939 (कस्टम URL स्कीम के लिए हैंडलर में अनुचित प्राधिकरण); संबंधित CWE-749 |
| प्रभावित घटक | com.airsweb.v10.MainActivity (निर्यातित डीप-लिंक हैंडलर) और MainActivityKt.WebViewPage में डीप-लिंक शाखा |
| कस्टम स्कीम | ehs-app:// |
| हमले का प्रकार | दूरस्थ (उपयोगकर्ता की सहभागिता आवश्यक — एक निर्मित लिंक खोलना) |
| प्रभाव | फ़िशिंग / सोशल इंजीनियरिंग: विश्वसनीय EcoOnline EHS ऐप के अंदर मनमानी हमलावर-नियंत्रित वेब सामग्री प्रस्तुत की जाती है (जैसे नकली लॉगिन), जो ऐप की डोमेन अनुमति-सूची को दरकिनार करती है |
| खोजकर्ता | Ahmet Mersin |
| दिनांक | घटना |
|---|
| 2026-01-13 | 0.2.499 के विरुद्ध PoC रिकॉर्ड किया गया |
| 2026-01-15 | MITRE को CVE अनुरोध प्रस्तुत किया गया (टिकट scr1979357) |
| 2026-02-27 | CVE-2026-26897 MITRE द्वारा निर्धारित |
| प्रकाशन से पहले | विक्रेता ने स्वीकार किया; समाधान 0.2.500 में जारी किया गया |
| 2026-03-04 | MITRE को प्रकाशन अनुरोध भेजा गया |
| 2026-05-06 | MITRE ने पूर्ण सार्वजनिक प्रकटीकरण URL का अनुरोध किया |
| 2026-06-03 | सार्वजनिक परामर्श प्रकाशित (यह रिपॉजिटरी) |