A serious security flaw (CVE-2024-31316) was found in Android's AccountManagerService, specifically in the onResult() method. This bug allows a local app with no special permissions to launch arbitrary background activities, possibly leading to escalation of privileges—all without a user even touching the device. If you’re an Android developer or concerned about device security, understanding how this vulnerability works is essential.

The Vulnerability in Simple Words

AccountManagerService is a system component used for managing user accounts on Android devices. It often interacts with multiple apps using *Parcels*—Android’s way of packaging data for inter-process communication.

The core issue in CVE-2024-31316 is that AccountManagerService’s onResult() method does not properly check what’s inside received Parcels. Due to this “parcel mismatch,” it’s possible for a malicious app to send a specially crafted response bundle. This can trick the system into launching any background activity the attacker wants.

Here’s a simple, step-by-step explanation

1. Attacker App Registers itself with AccountManager to add a fake account, or asks for some account operation.
2. Attacker Crafts a Malicious Bundle: When the system requests a result (like after authentication), the attacker sends back a Bundle with an Intent pointing to an arbitrary Activity.
3. onResult() Doesn't Check: Inside AccountManagerService.java, the onResult() code unpacks the Bundle but doesn’t properly verify the Intent.
4. Launches Activity in the Background: System then launches the unwanted activity, possibly with elevated privileges or in contexts where normal apps can’t.
5. No User Action Needed: This can happen in the background with no icon or notification, making detection hard.

This is a simplified version showing where the problem is

public void onResult(Bundle bundle) {
    // ... some code, assumes 'bundle' comes from a trustworthy source

    Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT);
    if (intent != null) {
        // Directly start the activity in the background!
        mContext.startActivity(intent);
        return;
    }
    // ... rest of the code
}

What’s wrong? There’s no check on the Intent, nor any restriction—it just runs, no matter who sent it or what it’s for.

An attacker can create a malicious app with the following code fragment

val badIntent = Intent()
badIntent.setClassName("com.android.settings", "com.android.settings.Settings\$DeveloperSettingsActivity")
// or even their own Activity
// badIntent.setComponent(ComponentName("attacker.package", "attacker.package.EvilActivity"))

val bundle = Bundle()
bundle.putParcelable(AccountManager.KEY_INTENT, badIntent)

// Now send it back to AccountManager's callback
resultReceiver.onResult(bundle)

If the system runs this, the developer settings (or any protected activity) might open in the background!

Who’s Affected?

- Android versions with AccountManagerService.java before this CVE was patched (check your device/ROM maintainers)

*Android Security Bulletin – June 2024*

Official Advisory

*Android Issue Tracker*

Google Issue #321407152

Patch Example

Proper way to fix this in AccountManagerService.java is to check the intent and add restrictions. For instance:

if (intent != null) {
    // Only start if the intent targets safe components, or require user confirmation
    if (/* safe to launch? */) {
        mContext.startActivity(intent);
    }
}

Conclusion

CVE-2024-31316 shows how a small oversight—like not checking parcel contents properly—can have huge security consequences. Arbitrary background activity launch lets local attackers quietly escalate privileges or execute actions users never approved. If you’re a developer: always carefully validate incoming data, especially from system-level callbacks.

Further Reading

- Android Security Best Practices
- How AccountManager Works

Timeline

Published on: 07/09/2024 21:15:13 UTC
Last modified on: 07/11/2024 15:05:39 UTC