Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are possible reasons that my AppWidgetProvider will receive data from 3rd party app in onReceive?

Tags:

java

android

Recently, I am experiencing some weird crash report from Firebase Crashlytics.

Caused by android.os.BadParcelableException: ClassNotFoundException when unmarshalling: id.dana.model.CurrencyAmountModel
       at android.os.Parcel.readParcelableCreator(Parcel.java:2305)
       at android.os.Parcel.readParcelable(Parcel.java:2255)
       at android.os.Parcel.readValue(Parcel.java:2162)
       at android.os.Parcel.readArrayMapInternal(Parcel.java:2495)
       at android.os.BaseBundle.unparcel(BaseBundle.java:221)
       at android.os.BaseBundle.getIntArray(BaseBundle.java:1164)
       at android.appwidget.AppWidgetProvider.onReceive(AppWidgetProvider.java:64)
       at com.yocto.wenote.widget.CalendarAppWidgetProvider.onReceive(CalendarAppWidgetProvider.java:234)

I feel weird because my app never have use/ access to class id.dana.model.CurrencyAmountModel. I have totally clueless where does the class id.dana.model.CurrencyAmountModel come from?

It seems like a 3rd party app is able to "inject" data into my AppWidgetProvider?

My AppWidgetProvider is defined as follow.

<receiver android:name="com.yocto.wenote.widget.CalendarAppWidgetProvider"
    android:label="@string/widget_calendar_name"
    android:exported="true" >
    <intent-filter >
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>

    <meta-data
        android:name="android.appwidget.provider"
        android:resource="@xml/calendar_widget_info" />
</receiver>
        
public class CalendarAppWidgetProvider extends AppWidgetProvider {

    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();

        ...

        super.onReceive(context, intent);
    }
}

Do you have any idea why does my AppWidgetProvider is receiving an unknown data id.dana.model.CurrencyAmountModel, and how I can avoid such?

Thanks.

like image 327
Cheok Yan Cheng Avatar asked Nov 06 '22 00:11

Cheok Yan Cheng


1 Answers

It seems like a 3rd party app is able to "inject" data into my AppWidgetProvider?

Sure. Your AppWidgetProvider is publicly accessible by any other app. Any app can send a broadcast to it that it will pick up.

Do you have any idea why does my AppWidgetProvider is receiving an unknown data id.dana.model.CurrencyAmountModel

Some app is sending a broadcast with a CurrencyAmountModel as an extra. Based on the stack trace and the implementation of AppWidgetProvider, my guess is that this invalid value is under the AppWidgetManager.EXTRA_APPWIDGET_IDS key. Hopefully, this is a bug in the other app and not something malicious.

how I can avoid such?

AFAIK, an AppWidgetProvider has to be exported for it to work. You could run an experiment and see if android:exported="false" still gives you a working app widget, but it would surprise me.

If that fails, you could wrap the super.onReceive() in a try/catch block to prevent the crash. Given the AppWidgetProvider implementation, if your catch block is invoked, probably your provider did not get called with any of the standard callbacks (e.g., onUpdate()). You could add some logging to try to get a sense of whether affected users get any good super.onReceive() calls:

  • If they do, the probably the app widget is working normally other than these rogue broadcasts, so you could write off the failures as just some annoyance

  • If they are always affected, you might need to try calling onUpdate() yourself from time to time

like image 85
CommonsWare Avatar answered Nov 14 '22 23:11

CommonsWare