PSA: FLAG_SECURE Window Leaks
FLAG_SECURE
can be applied to a Window
— such as an activity’s
Window
— to secure its contents against screen recordings and so on.
Authors of widgets or other UI elements that show their own windows need to:
-
Examine the activity that those elements are a part of and see if that activity is using
FLAG_SECURE
to protect its contents. If it is, the UI element needs to applyFLAG_SECURE
to any windows it opens up on behalf of that activity, such as a popup, so that the entire activity UI is secure. -
Or, the UI element needs to expose the
Window
objects via a public API, so thatFLAG_SECURE
can be applied where needed.
Google does not do either of these things on:
AutoCompleteTextView
Spinner
(both dropdown and dialog modes)- the overflow menu of the framework-supplied action bar
ShareActionProvider
Toast
and probably
many others,
as my investigation continues. The only scenario that seems to be discussed
much in this area is Dialog
, where you can use getWindow()
to apply
FLAG_SECURE
yourself… if you know to do that.
Since they lack FLAG_SECURE
(despite the activity having it),
content in these UI elements will be leaked into:
-
Screenshots taken by the media projection APIs on Android 5.0+
-
Screencasts taken by the media projection APIs on Android 5.0+ (e.g., Jake Wharton’s Telecine)
-
The Assist API (e.g., Now On Tap) on Android 6.0+
-
Android Studio screen recordings on Android 4.4+
and possibly other areas as well. While all of those things have their
own security (e.g., user authorization of media projection API usage), we still
have lost a layer of security by the Android framework not propagating
FLAG_SECURE
to other windows (or allowing developers to readily do it
themselves).
For example, this screencast shows an activity that has FLAG_SECURE
applied, yet you can see all sorts of child windows from the aforementioned
UI elements still show up.
Google considers this to be working as intended.
You may disagree with Google’s assessment. If so, I have more details on the problem, along with some code to help deal with the bug, in my CWAC-Security library.
I would like to thank Vivart Pandey, who first pointed out this problem.