How to Protect Against Android Overlay Attacks
The Android overlay is a feature used by an app to appear on top of another app. Overlays are commonly used to display floating views such as the chat bubbles in Facebook Messenger or to display a temporary message or alert. They are often used to provide a more convenient user experience by allowing users to access certain features or information without leaving the app they are currently using. However, the benefits of this feature come with a big risk as Android overlays can, unfortunately, be used for malicious purposes.
Privilege escalation and theft of sensitive data are often the results of successful overlay attacks. Android overlays can draw a full window on top of a legitimate app, the overlay target, to impersonate the specified app and increase its chance of performing a successful phishing attack. Additionally, malicious overlays can cover partial, but critical, areas of the screen, such as the text in a message box which indicates what permissions are requested by the app. While covering the legitimate app permissions text, the malicious app requests higher privileges, making the user intentionally unaware of what is happening.
The image below illustrates two different Android overlay malware attack scenarios. Image B shows a partial screen overlay attack as a malicious view is being drawn on top of a specific location to trick the user. Image C is a full overlay covering the full screen to ask for sensitive user information. This type of overlay is often well-timed (eg. creating the overlay when the user starts a specific banking application) to trick the user into believing a legitimate application is asking for sensitive information.
In this post, we will guide you towards some easy steps that you can take to protect against Android overlays, knowing that the Android SDK improvements eventually make these steps redundant.
Seamlessly protect against malware with DexGuard’s built-in malware protection feature >
How do you protect against Android overlays as a developer?
Starting at API 31 (Android 12), Android introduced a definitive feature to protect against malicious overlays. To use this feature, you call the method "setHideOverlayWindows(true)" on your specified activity windows. Developers should apply this to every activity view that requests sensitive information from the user, such as pin codes, passwords, credit card details, etc. Doing so will prevent non-system overlays from obscuring such views on recent android versions.
Button detectOverlayButton = (Button)findViewById(R.id.btnDetect);
detectOverlayButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v)
{
MainActivity.this.getWindow().setHideOverlayWindows(true);
}
});
For applications below API 31, the alternative option is to check whether a touch event has been obscured by an overlay. There are two types of obscured touches, named 'partially obscured' and 'obscured'; the latter is true if an overlay is located at the touch location. When an overlay is present but does not cover a touch this will be seen as a partially obscured touch.
Android API 9 (Android 2) added three valuable methods for detecting overlay malware based on touch events. The methods onTouch, onFilterTouchEventForSecurity, and setFilterTouchesWhenObscured are made available in API 9 and higher and can be used to detect obscured touch events.
ViewGroup view = findViewById(R.id.main_view);
view.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Boolean badTouch = ((event.getFlags() & FLAG_WINDOW_IS_OBSCURED) != 0)
// do not consume event if obscured
return badTouch;
}
});
The setFilterTouchesWhenObscured can be used as a method to filter obscured touches specifically. Another way to apply this method to a view is by adding the 'android:filterTouchesWhenObscured' to the layout attribute.
ViewGroup view = findViewById(R.id.main_view);
view.setFilterTouchesWhenObscured(true);
The onFilterTouchEventForSecurity can also be used to filter specific MotionEvents to prevent obscure touches.
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
return onFilterTouchEventForSecurity(event);
}
@Override
public boolean onFilterTouchEventForSecurity(MotionEvent event) {
// Add custom security check
int flags = event.getFlags();
Boolean badTouch = (((flags & FLAG_WINDOW_IS_PARTIALLY_OBSCURED) != 0)
|| ((flags & FLAG_WINDOW_IS_OBSCURED) != 0));
if (badTouch)
{
// consume touch event to block touch
return false;
}
return super.onFilterTouchEventForSecurity(event);
}
Furthermore, the onTouch can use the FLAG_WINDOW_IS_OBSCURED flag to detect obscured touches in a specified view. Another onTouch flag has been added in API 29 (Android 10), introducing FLAG_WINDOW_IS_PARTIALLY_OBSCURED for more precise detection of partially obscured touches.
ViewGroup view = findViewById(R.id.main_view);
view.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int flags = event.getFlags();
Boolean badTouch = (((flags & FLAG_WINDOW_IS_PARTIALLY_OBSCURED) != 0)
|| ((flags & FLAG_WINDOW_IS_OBSCURED) != 0));
// do not consume event if obscured
return badTouch;
}
});
Check out our Android Overlay Malware Detection Example repo on GitHub which uses all said techniques.
Learn how to defend against malware in our Mobile Application Security Research Center >
Comprehensive Evaluation of said techniques
On API 31+, you are fully protected against any non-system overlay for every view on which we apply "setHideOverlayWindows(true)". However, any API below API 31 might be vulnerable to being an overlay target for overlays that do not pass through touch events. The obscure touch event detections won't work for overlays that block touch events from going to the view, making the onTouch ineffective against a particular set of Android overlay malware attacks, known as full overlay phishing attacks. These phishing attacks work by posing as legitimate applications as they initiate a full overlay at the same time the user launches a legitimate application, tricking the user into entering sensitive information into the malicious application instead.
In light of the gaps found prior to API 31, using Multi-Factor Authentication makes it possible to provide additional security against such phishing attacks. For example, adding e-mail or SMS verification to authenticate a new device is a good start. Aiming for a more robust solution like Google Authenticator on every login attempt would be ideal from a security point of view as well.
Additionally, API 23 (Android 6) introduced a new overlay permission flag named ACTION_MANAGE_OVERLAY_PERMISSION, which is required for any app to draw an overlay. This overlay permission is automatically granted when an app is installed from the Official Google Play Store. Fortunately, apps installed from other sources will prompt an explicit message requesting overlay permissions, slightly reducing the risk of an Android overlay attack.
Conclusion
In modern Android versions, developers can successfully block any non-system Android overlay to protect against overlay attacks. Developers that target systems below API 31 still have an alternative technique available that can determine if the application interaction has been influenced by any overlay, allowing developers to take action by potentially restricting certain touch events, resulting in an application that can reduce the risk of malicious overlays for as low as target API 9.
If you are unsure if your mobile app is susceptible to being an Android overlay target, you may want to consider scanning it using a mobile application security testing tool such as AppSweep. AppSweep is a free service that you can utilize to quickly identify and fix security issues in your application.