In early 2023, a significant vulnerability was found in the Android OS, affecting several versions from Android 11 up to the latest Android 13. This vulnerability, tracked as CVE-2023-20906, allows a local attacker or a malicious app to silently gain escalated permissions after an app is updated to target a higher SDK version — all without any user interaction. The underlying problem is a flaw in Android's permission management, specifically in PermissionManagerService.java.

In this long read, we'll break down how this vulnerability works, show relevant code snippets, explain how an attacker might exploit it, and share resources for further reading.

What is CVE-2023-20906?

CVE-2023-20906 is a security vulnerability in the way Android manages permissions after an app's targetSdkVersion changes. Normally, when an app updates its target SDK (e.g., from Android 11 to Android 12), Android may change which permissions are automatically granted or require user consent. This is intended to enforce stricter privacy and security standards as the Android platform evolves.

However, in this case, a logic flaw in PermissionManagerService.java allows certain permissions to be silently granted after an app updates its target SDK. This bypasses the usual security checks and potentially gives malicious apps elevated access to sensitive device features or user data.

The Core Problem

Within the Android OS source code, there's a function called onPackageAddedInternal in the PermissionManagerService class. This function is responsible for handling permissions when a new package (app) is added or updated. The vulnerability results from not properly validating previous permissions versus new permissions triggered by a target SDK change.

Does the permission require explicit user acknowledgment?

If an app is updated with a higher target SDK, some permissions (which previously required user approval) might now be set to auto-grant due to faulty logic.

Here's a simplified pseudocode representation to illustrate the flaw

// Inside PermissionManagerService.java

void onPackageAddedInternal(PackageParser.Package pkg, boolean... etc) {
    // ... omitted code ...

    // Before granting permission, decisions are made here
    if (shouldGrantPermission(pkg, permission)) {
        grantPermission(pkg, permission);
    }

    // ... omitted code ...
}

The function shouldGrantPermission() fails to check if a permission should stay ungranted when just raising the target SDK version. Instead, it may grant permissions that should require user consent — but does so silently.

In the actual vulnerable code, the permission grant status is not carried over correctly, leading to this bypass.

Attack Scenario

1. Malicious App Installation: A user installs an app that targets, say, Android 11 (SDK 30), asking only for basic permissions.
2. Update with Higher Target SDK: The app "updates" (via Play Store or manual update) to target Android 12 or 13, asking for new permissions (e.g., access to camera, location, SMS).
3. Silent Grant: Due to the vulnerability, when the app updates, the system incorrectly auto-grants these new dangerous permissions *without* any prompt or warning to the user.
4. Abuse: The app now silently gains higher privileges and can read/send SMS, access the camera, or get location data.

`java

if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS) == PackageManager.PERMISSION_GRANTED) {
         // Permission auto-granted unexpectedly!

Result:

- The newly requested permission (READ_SMS) will be granted to the app automatically, violating expected security behavior.

A full demonstration and more details can be found below

- Android Security Bulletin, June 2023
- CVE-2023-20906 at NVD
- AOSP Commit Fixing the Bug

How Is It Fixed?

The patch adds proper logic in onPackageAddedInternal to keep previously revoked or ungranted permissions in their state. It no longer automatically grants permissions just because the target SDK version was bumped.

Patch example

// Additional check introduced in the fix:
if (previouslyRevoked(permission, pkg)) {
    // Do not auto-grant!
    continue;
}

Conclusion

CVE-2023-20906 highlights how even a small oversight in permission handling logic can create major security holes, silently escalating app privileges as developers bump target SDKs. If you are a developer or end-user, staying updated and understanding what changes when you (or apps) move to a higher API level is more important than ever.

References

- Android Security June 2023 Bulletin
- CVE-2023-20906 at NVD
- Patch Commit in AOSP
- Android Developers - Declaring Permissions


Stay safe and keep your devices updated!  
*If you have more questions about Android security or this CVE, feel free to reply below.*

Timeline

Published on: 03/24/2023 20:15:00 UTC
Last modified on: 03/29/2023 07:32:00 UTC