Securing Apps From Android 8.0 Autofill

Back in April, I pointed out that Android 8.0’s autofill ignores FLAG_SECURE. This provides an avenue for well-crafted malware to get data out of arbitrary apps, including apps that users may not realize are handing over data to some other app.

And while I still think that Google’s FLAG_SECURE choice was the wrong one, I’m happy to see that O Developer Preview 3 gives us another approach. There is an android:importantForAutofill attribute that you can place on any View, and a corresponding setImportantForAutofill() method. Given those:

  • To block autofill from seeing the value of a sensitive widget, use android:importantForAutofill="no" or setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO) on the affected View

  • To block autofill for an entire activity, use this in onCreate() of the activity:

getWindow()
  .getDecorView()
  .setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS);

In this case, no really does mean “no”, and the data in those widgets should not be supplied to the autofill service. For containers, noExcludeDescendants or IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS blocks both the container itself and all children down that branch of the view hierarchy.

Apps that contain sensitive data — particularly those for which autofill is a bug, not a feature — can use this approach to defend their users.

If you are nervous that even these options may prove insufficient (e.g., in ODP2, they did not work), you can use the AutofillManager to see if autofill is enabled, and, if it is, take evasive action:

if (getSystemService(android.view.autofill.AutofillManager.class).isEnabled()) {
  Toast.makeText(this, "Ick!", Toast.LENGTH_LONG).show();
  finish();
}