Securing Jetpack Compose
Jetpack Compose is nothing short of a complete overhaul of how we create Android UIs.
This sort of major change is unusual, to say the least. This gives us a great opportunity
to fix all sorts of limitations of the preceding system… including how it impacts
user privacy and security. Two examples are FLAG_SECURE
and password text entry.
Compose and FLAG_SECURE
You can add FLAG_SECURE
to an Android window to prevent that window from being included
in screenshots and screencasts. However, you need to have access to the window in order
to be able to do that. Adding FLAG_SECURE
to an activity
is easy. Adding FLAG_SECURE
to a dialog is not that bad. However, lots of widgets and
other classic UI elements create windows: Spinner
, AutoCompleteTextView
,
ShareActionProvider
, etc. We do not have access to their windows, so we cannot
add FLAG_SECURE
to them. And the implementations of those widgets fail to set
FLAG_SECURE
themselves, if they are being used from a window that itself has
FLAG_SECURE
. As a result, the screenshot blocking is leaky,
and resulted in security flaws in password managers
among other apps.
Ideally, Jetpack Compose allows us to specify a policy that results in FLAG_SECURE
being used by any windows that it creates. Even better would be if the default
policy were to propagate FLAG_SECURE
: if FLAG_SECURE
is set on an activity or fragment that
is displaying a composable, then those composables should also set FLAG_SECURE
on any windows that they create.
At least as of a month ago, none of that was available.
So, I filed issues to get FLAG_SECURE
be honored in popup windows
and dialogs.
Compose and Passwords
A general recommendation with passwords is to wipe them out of memory as soon as you no longer need them. That way, security flaws in the app or certain other types of attacks can no longer obtain (“exfiltrate”) those passwords.
In Java, though, String
is immutable, and the same is true in Kotlin/JVM. This is why
in Java it is generally recommended to use char[]
, as you can replace the array elements.
EditText
uses an Editable
, which is a form of CharSequence
. We can get at the char[]
and clear it as needed.
Unfortunately, at least as of a month ago, PasswordTextField
uses String
instead of char[]
. Ideally, PasswordTextField
switches to char[]
(perhaps
wrapped in a CharSequence
or something). So, I filed an issue for that too.
However, yesterday that issue’s priority was dropped, which is not reassuring.
How You Can Help!
If you are a security expert or a seasoned developer, and you can think of other privacy/security aspects of a UI toolkit that might not be handled by Jetpack Compose, your input would be very valuable. If you are in position to work with Compose and can determine whether your concerns are addressed, that would be wonderful, and please file issues for any gaps that you find. If you know of areas of concern but are not in position to see how Compose fares, feel free to contact me, and I will see what I can find.
Also, keep tabs on the issues that I filed already (linked above), if they interest you.
Since Jetpack Compose is shipping in library form, there is always the possibility of security-related fixes being added after a 1.0 edition of Compose ships. However, I suspect that it will be much easier to get these problems solved now while APIs are fluid.
I am hoping that Jetpack Compose can be world-class, not just in terms of the programming APIs and end-user experience, but also in terms of privacy and security.