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"
orsetImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO)
on the affectedView
-
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();
}