VYPR
Critical severityNVD Advisory· Published Feb 10, 2023· Updated Mar 24, 2025

CodenameOne implicit intent for sensitive communication

CVE-2022-4903

Description

A vulnerability was found in CodenameOne 7.0.70. It has been classified as problematic. Affected is an unknown function. The manipulation leads to use of implicit intent for sensitive communication. It is possible to launch the attack remotely. The complexity of an attack is rather high. The exploitability is told to be difficult. Upgrading to version 7.0.71 is able to address this issue. The patch is identified as dad49c9ef26a598619fc48d2697151a02987d478. It is recommended to upgrade the affected component. VDB-220470 is the identifier assigned to this vulnerability.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

CodenameOne 7.0.70 uses an implicit PendingIntent, potentially allowing malicious apps to intercept or modify sensitive communication.

Analysis

CodenameOne version 7.0.70 contains a vulnerability where the framework uses an implicit PendingIntent for sensitive communication, such as push notification actions. The root cause is the use of PendingIntent.FLAG_CANCEL_CURRENT without setting FLAG_IMMUTABLE, which can allow other applications to read or modify the intent's data [1][3].

Exploitation requires an attacker to be able to run a malicious application on the same device, as the attack is performed remotely by intercepting or modifying the PendingIntent. The attack complexity is rated as high, and exploitability is considered difficult [2]. The vulnerability is classified as problematic rather than critical.

An attacker who successfully exploits this could potentially intercept sensitive information passed through the implicit intent, or redirect the intent to a malicious component, leading to data disclosure or privilege escalation. However, the specific impact depends on the application's use of the affected function.

The issue has been fixed in version 7.0.71, with the commit dad49c9ef26a598619fc48d2697151a02987d478 introducing FLAG_IMMUTABLE for Android API 23 and above, while falling back to FLAG_CANCEL_CURRENT for older versions [3][4]. Users are recommended to upgrade to the latest version. The vulnerability is tracked as VDB-220470.

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
com.codenameone:codenameone-coreMaven
< 7.0.717.0.71

Affected products

3

Patches

1
dad49c9ef26a

Fixed #3583 Pending Intent vulnerability

https://github.com/codenameone/CodenameOneShai AlmogApr 23, 2022via ghsa
5 files changed · +54 31
  • Ports/Android/src/com/codename1/impl/android/AndroidImplementation.java+37 9 modified
    @@ -775,7 +775,36 @@ private static PushActionCategory[] getInstalledPushActionCategories(Context con
             }
    
             return out.toArray(new PushActionCategory[out.size()]);
    
         }
    
    -    
    
    +
    
    +    public static PendingIntent createPendingIntent(Context ctx, int value, Intent intent) {
    
    +        if (android.os.Build.VERSION.SDK_INT >= 23) {
    
    +            // PendingIntent.FLAG_IMMUTABLE
    
    +            return PendingIntent.getActivity(ctx, value, newIntent, 67108864);
    
    +        } else {
    
    +            return PendingIntent.getActivity(ctx, value, newIntent, PendingIntent.FLAG_CANCEL_CURRENT);
    
    +        }
    
    +    }
    
    +
    
    +    public static PendingIntent getPendingIntent(Context ctx, int value, Intent intent) {
    
    +        if (android.os.Build.VERSION.SDK_INT >= 23) {
    
    +            // PendingIntent.FLAG_IMMUTABLE
    
    +            return PendingIntent.getService(ctx, value, newIntent, 67108864);
    
    +        } else {
    
    +            return PendingIntent.getService(ctx, value, newIntent, PendingIntent.FLAG_CANCEL_CURRENT);
    
    +        }
    
    +        PendingIntent.getService
    
    +    }
    
    +
    
    +    public static PendingIntent getBroadcastPendingIntent(Context ctx, int value, Intent intent) {
    
    +        if (android.os.Build.VERSION.SDK_INT >= 23) {
    
    +            // PendingIntent.FLAG_IMMUTABLE
    
    +            return PendingIntent.getBroadcast(ctx, value, newIntent, 67108864);
    
    +        } else {
    
    +            return PendingIntent.getBroadcast(ctx, value, newIntent, PendingIntent.FLAG_CANCEL_CURRENT);
    
    +        }
    
    +        PendingIntent.getService
    
    +    }
    
    +
    
         /**
    
          * Adds actions to a push notification.  This is called by the Push broadcast receiver probably before 
    
          * Codename One is initialized
    
    @@ -811,7 +840,7 @@ public static void addActionsToNotification(PushActionsProvider provider, String
             for (PushAction action : category.getActions()) {
    
                 Intent newIntent = (Intent)targetIntent.clone();
    
                 newIntent.putExtra("pushActionId", action.getId());
    
    -            PendingIntent contentIntent = PendingIntent.getActivity(context, requestCode++, newIntent, PendingIntent.FLAG_CANCEL_CURRENT);
    
    +            PendingIntent contentIntent = createPendingIntent(context, requestCode++, newIntent);
    
                 try {
    
                     int iconId = 0;
    
                     try { iconId = Integer.parseInt(action.getIcon());} catch (Exception ex){}
    
    @@ -7093,7 +7122,7 @@ public Object notifyStatusBar(String tickerText, String contentTitle,
     
    
             Intent notificationIntent = new Intent();
    
             notificationIntent.setComponent(activityComponentName);
    
    -        PendingIntent contentIntent = PendingIntent.getActivity(getContext(), 0, notificationIntent, 0);
    
    +        PendingIntent contentIntent = createPendingIntent(getContext(), 0, notificationIntent);
    
     
    
     
    
             NotificationCompat.Builder builder = new NotificationCompat.Builder(getContext())
    
    @@ -10416,20 +10445,19 @@ public void scheduleLocalNotification(LocalNotification notif, long firstTime, i
                 //intent.putExtra("backgroundClass", getBackgroundLocationListener().getName());
    
                 //an ugly workaround to the putExtra bug 
    
                 intent.setData(Uri.parse("http://codenameone.com/a?" + getBackgroundFetchListener().getClass().getName()));
    
    -            PendingIntent pendingIntent = PendingIntent.getService(context, 0,
    
    -                    intent,
    
    -                    PendingIntent.FLAG_UPDATE_CURRENT);
    
    +            PendingIntent pendingIntent = getPendingIntent(context, 0,
    
    +                    intent);
    
                 notificationIntent.putExtra(LocalNotificationPublisher.BACKGROUND_FETCH_INTENT, pendingIntent);
    
     
    
             } else {
    
                 contentIntent.setData(Uri.parse("http://codenameone.com/a?LocalNotificationID="+Uri.encode(notif.getId())));
    
             }
    
    -        PendingIntent pendingContentIntent = PendingIntent.getActivity(getContext(), 0, contentIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    
    +        PendingIntent pendingContentIntent = createPendingIntent(getContext(), 0, contentIntent);
    
     
    
             notificationIntent.putExtra(LocalNotificationPublisher.NOTIFICATION_INTENT, pendingContentIntent);
    
     
    
     
    
    -        PendingIntent pendingIntent = PendingIntent.getBroadcast(getContext(), 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    
    +        PendingIntent pendingIntent = getBroadcastPendingIntent(getContext(), 0, notificationIntent);
    
     
    
             AlarmManager alarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
    
             if (BACKGROUND_FETCH_NOTIFICATION_ID.equals(notif.getId())) {
    
    @@ -10462,7 +10490,7 @@ public void cancelLocalNotification(String notificationId) {
             Intent notificationIntent = new Intent(getContext(), LocalNotificationPublisher.class);
    
             notificationIntent.setAction(getContext().getApplicationInfo().packageName + "." + notificationId);
    
     
    
    -        PendingIntent pendingIntent = PendingIntent.getBroadcast(getContext(), 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    
    +        PendingIntent pendingIntent = getBroadcastPendingIntent(getContext(), 0, notificationIntent);
    
             AlarmManager alarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
    
             alarmManager.cancel(pendingIntent);
    
         }
    
    
  • Ports/Android/src/com/codename1/impl/android/CodenameOneActivity.java+2 2 modified
    @@ -428,15 +428,15 @@ public boolean isBackground() {
         public void registerForPush(String key) {
             Intent registrationIntent = new Intent("com.google.android.c2dm.intent.REGISTER");
             registrationIntent.setPackage("com.google.android.gms");
    -        registrationIntent.putExtra("app", PendingIntent.getBroadcast(this, 0, new Intent(), 0)); // boilerplate
    +        registrationIntent.putExtra("app", AndroidImplementation.getBroadcastPendingIntent(this, 0, new Intent())); // boilerplate
             registrationIntent.putExtra("sender", key);
             startService(registrationIntent);
         }
     
         public void stopReceivingPush() {
             Intent unregIntent = new Intent("com.google.android.c2dm.intent.UNREGISTER");
             unregIntent.setPackage("com.google.android.gms");
    -        unregIntent.putExtra("app", PendingIntent.getBroadcast(this, 0, new Intent(), 0));
    +        unregIntent.putExtra("app", AndroidImplementation.getBroadcastPendingIntent(this, 0, new Intent()));
             startService(unregIntent);
         }
     
    
  • Ports/Android/src/com/codename1/impl/android/PushNotificationService.java+3 2 modified
    @@ -103,7 +103,8 @@ public void onDestroy() {
         
         public abstract PushCallback getPushCallbackInstance();
         public abstract Class getStubClass();
    -    
    +
    +
         @Override
         public void push(final String value) {
             final PushCallback callback = getPushCallbackInstance();
    @@ -116,7 +117,7 @@ public void run() {
             } else {
                 NotificationManager nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
                 Intent newIntent = new Intent(this, getStubClass());
    -            PendingIntent contentIntent = PendingIntent.getActivity(this, 0, newIntent, PendingIntent.FLAG_CANCEL_CURRENT);
    +            PendingIntent contentIntent = AndroidImplementation.createPendingIntent(this, 0, newIntent);
     
     
     
    
  • Ports/Android/src/com/codename1/location/AndroidLocationPlayServiceManager.java+10 14 modified
    @@ -189,9 +189,8 @@ public void run() {
                                 if (bgListenerClass != null) {
    
                                     intent.setData(Uri.parse("http://codenameone.com/a?" + bgListenerClass.getName()));
    
                                 }
    
    -                            PendingIntent pendingIntent = PendingIntent.getService(context, 0,
    
    -                                    intent,
    
    -                                    PendingIntent.FLAG_UPDATE_CURRENT);
    
    +                            PendingIntent pendingIntent = AndroidImplementation.getPendingIntent(context, 0,
    
    +                                    intent);
    
                                 inMemoryBackgroundLocationListener = AndroidLocationPlayServiceManager.this;
    
     
    
     
    
    @@ -228,16 +227,15 @@ private PendingIntent createBackgroundPendingIntent(boolean forceService) {
                 Intent intent = new Intent(context, BackgroundLocationBroadcastReceiver.class);
    
                 intent.setData(Uri.parse("http://codenameone.com/a?" + bgListenerClass.getName()));
    
                 intent.setAction(BackgroundLocationBroadcastReceiver.ACTION_PROCESS_UPDATES);
    
    -            PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    
    +            PendingIntent pendingIntent = AndroidImplementation.getBroadcastPendingIntent(context, 0, intent);
    
                 return pendingIntent;
    
             } else {
    
     
    
     
    
                 Intent intent = new Intent(context, BackgroundLocationHandler.class);
    
                 intent.setData(Uri.parse("http://codenameone.com/a?" + bgListenerClass.getName()));
    
    -            PendingIntent pendingIntent = PendingIntent.getService(context, 0,
    
    -                    intent,
    
    -                    PendingIntent.FLAG_UPDATE_CURRENT);
    
    +            PendingIntent pendingIntent = AndroidImplementation.getPendingIntent(context, 0,
    
    +                    intent);
    
                 return pendingIntent;
    
             }
    
         }
    
    @@ -290,9 +288,8 @@ public void run() {
                                 if (bgListenerClass != null) {
    
                                     intent.putExtra("backgroundClass", bgListenerClass.getName());
    
                                 }
    
    -                            PendingIntent pendingIntent = PendingIntent.getService(context, 0,
    
    -                                    intent,
    
    -                                    PendingIntent.FLAG_UPDATE_CURRENT);
    
    +                            PendingIntent pendingIntent = AndroidImplementation.getPendingIntent(context, 0,
    
    +                                    intent);
    
     
    
                                 //LocationServices.FusedLocationApi.removeLocationUpdates(getmGoogleApiClient(), pendingIntent);
    
                                 removeLocationUpdates(context, pendingIntent);
    
    @@ -481,16 +478,15 @@ private PendingIntent createGeofencePendingIntent(Class geofenceListenerClass, c
                 intent.setAction(BackgroundLocationBroadcastReceiver.ACTION_PROCESS_GEOFENCE_TRANSITIONS);
    
                 intent.setData(Uri.parse("http://codenameone.com/a?" + geofenceListenerClass.getName()));
    
                 //intent.setAction(BackgroundLocationBroadcastReceiver.ACTION_PROCESS_GEOFENCE_TRANSITIONS);
    
    -            geofencePendingIntent = PendingIntent.getBroadcast(AndroidNativeUtil.getContext().getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    
    +            geofencePendingIntent = AndroidImplementation.getBroadcastPendingIntent(AndroidNativeUtil.getContext().getApplicationContext(), 0, intent);
    
                 return geofencePendingIntent;
    
             } else {
    
     
    
                 Intent intent = new Intent(context, GeofenceHandler.class);
    
                 intent.putExtra("geofenceClass", geofenceListenerClass.getName());
    
                 intent.putExtra("geofenceID", gf.getId());
    
    -            PendingIntent pendingIntent = PendingIntent.getService(context, 0,
    
    -                    intent,
    
    -                    PendingIntent.FLAG_UPDATE_CURRENT);
    
    +            PendingIntent pendingIntent = AndroidImplementation.getPendingIntent(context, 0,
    
    +                    intent);
    
     
    
     
    
                 return pendingIntent;
    
    
  • Ports/Android/src/com/codename1/media/BackgroundAudioService.java+2 4 modified
    @@ -53,6 +53,7 @@
     
     import android.text.TextUtils;
     
    +import com.codename1.impl.android.AndroidImplementation;
     import com.codename1.ui.Display;
     
     
    @@ -267,9 +268,6 @@ void showPausedNotification() {
         }
     
     
    -
    -
    -
         private void initMediaSession() {
             ComponentName mediaButtonReceiver = new ComponentName(getApplicationContext(), MediaButtonReceiver.class);
             mMediaSessionCompat = new MediaSessionCompat(getApplicationContext(), "Tag", mediaButtonReceiver, null);
    @@ -279,7 +277,7 @@ private void initMediaSession() {
     
             Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
             mediaButtonIntent.setClass(this, MediaButtonReceiver.class);
    -        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, mediaButtonIntent, 0);
    +        PendingIntent pendingIntent = AndroidImplementation.getBroadcastPendingIntent(this, 0, mediaButtonIntent);
             mMediaSessionCompat.setMediaButtonReceiver(pendingIntent);
     
             setSessionToken(mMediaSessionCompat.getSessionToken());
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.