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.

Want an expert opinion on your Android app architecture decisions? Perhaps Mark Murphy can help!