The sample shows an app that uses setHideOverlayWindows(true) at the activity level (available from Android 12, API level 31) and declares the required HIDE_OVERLAY_WINDOWS permission in the manifest. Unlike the view-level protections in Missing Overlay Protection on a Sensitive View, this approach prevents any overlay window from appearing over the entire activity.
packageorg.owasp.mastestappimportandroid.app.Activityimportandroid.content.Contextimportandroid.graphics.Colorimportandroid.os.Buildimportandroid.view.Gravityimportandroid.view.ViewGroupimportandroid.widget.Buttonimportandroid.widget.FrameLayoutimportandroid.widget.LinearLayoutimportandroid.widget.Toast// SUMMARY: This sample demonstrates activity-level overlay protection using setHideOverlayWindows(true),// which prevents any overlay window from appearing over the activity. It requires the HIDE_OVERLAY_WINDOWS// permission and targets Android 12 (API level 31) and above.classMastgTest(privatevalcontext:Context){valshouldRunInMainThread=truefunmastgTest():String{vallayout=LinearLayout(context).apply{orientation=LinearLayout.VERTICALgravity=Gravity.CENTERsetBackgroundColor(Color.TRANSPARENT)}valhalfWidth=(context.resources.displayMetrics.widthPixels*0.5).toInt()valbuttonParams=LinearLayout.LayoutParams(halfWidth,LinearLayout.LayoutParams.WRAP_CONTENT).apply{gravity=Gravity.CENTER_HORIZONTALtopMargin=24}valvulnerableButton=Button(context).apply{text="Confirm Payment"setOnClickListener{Toast.makeText(context,"Button clicked",Toast.LENGTH_SHORT).show()}}layout.addView(vulnerableButton,buttonParams)(contextas?Activity)?.let{activity->// PASS: [MASTG-TEST-0x01] The activity uses setHideOverlayWindows(true) to prevent overlay// windows from appearing over this activity, protecting all sensitive UI elements at once.if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.S){activity.window.setHideOverlayWindows(true)}valroot=activity.findViewById<ViewGroup>(android.R.id.content)if(layout.parent==null){root.addView(layout,FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,FrameLayout.LayoutParams.MATCH_PARENT))}}return"Created button with activity level overlay protection"}}
rules:-id:mastg-android-overlay-protection-setfiltertoucheswhenobscuredseverity:INFOlanguages:-javametadata:summary:DetectsusageofsetFilterTouchesWhenObscuredmethodforoverlayattackprotectionmessage:"[MASVS-PLATFORM-3] setFilterTouchesWhenObscured is used to protect against overlay attacks"pattern:$VIEW.setFilterTouchesWhenObscured(...)-id:mastg-android-overlay-protection-onfiltertoucheventforsecurityseverity:INFOlanguages:-javametadata:summary:DetectsoverridingofonFilterTouchEventForSecurityforcustomoverlayprotectionmessage:"[MASVS-PLATFORM-3] onFilterTouchEventForSecurity is overridden for custom overlay protection"pattern:|publicbooleanonFilterTouchEventForSecurity(...){...}-id:mastg-android-overlay-protection-flag-window-is-obscuredseverity:INFOlanguages:-javametadata:summary:DetectschecksforFLAG_WINDOW_IS_OBSCUREDflagtodetectoverlayattacksmessage:"[MASVS-PLATFORM-3] FLAG_WINDOW_IS_OBSCURED is checked to detect overlay attacks"pattern-either:-pattern:$EVENT.getFlags()&MotionEvent.FLAG_WINDOW_IS_OBSCURED-pattern:($EVENT.getFlags()&MotionEvent.FLAG_WINDOW_IS_OBSCURED)!=0-id:mastg-android-overlay-protection-flag-window-is-partially-obscuredseverity:INFOlanguages:-javametadata:summary:DetectschecksforFLAG_WINDOW_IS_PARTIALLY_OBSCUREDflagtodetectoverlayattacksmessage:"[MASVS-PLATFORM-3] FLAG_WINDOW_IS_PARTIALLY_OBSCURED is checked to detect overlay attacks"pattern-either:-pattern:$EVENT.getFlags()&MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED-pattern:($EVENT.getFlags()&MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED)!=0-id:mastg-android-overlay-protection-xml-attributeseverity:INFOlanguages:-xmlmetadata:summary:DetectsfilterTouchesWhenObscuredattributeinlayoutXMLfilesmessage:"[MASVS-PLATFORM-3] android:filterTouchesWhenObscured attribute is used to protect against overlay attacks"pattern:android:filterTouchesWhenObscured="true"-id:mastg-android-overlay-protection-sethideoverlaywindowsseverity:INFOlanguages:-javametadata:summary:DetectsusageofsetHideOverlayWindowstopreventoverlaywindowsfromappearingovertheactivitymessage:"[MASVS-PLATFORM-3] setHideOverlayWindows is used to prevent overlay windows from appearing over this window"pattern:$WINDOW.setHideOverlayWindows(...)-id:mastg-android-overlay-protection-hide-overlay-windows-permissionseverity:INFOlanguages:-xmlmetadata:summary:DetectsHIDE_OVERLAY_WINDOWSpermissioninthemanifest,requiredforsetHideOverlayWindowsmessage:"[MASVS-PLATFORM-3] HIDE_OVERLAY_WINDOWS permission is declared, required to use setHideOverlayWindows"pattern:android:name="android.permission.HIDE_OVERLAY_WINDOWS"
run.sh
1234
#!/bin/bash# Run semgrep to detect setHideOverlayWindows in the decompiled code and HIDE_OVERLAY_WINDOWS permission in the manifestNO_COLOR=truesemgrep-c../../../../rules/mastg-android-overlay-protection.yml./MastgTest_reversed.java./AndroidManifest_reversed.xml--text>output.txt
The test passes because the app implements activity-level overlay protection:
The setHideOverlayWindows(true) call (detected in the code output) instructs the system to hide any TYPE_APPLICATION_OVERLAY windows when this activity is in the foreground, effectively preventing overlay attacks on all UI elements in the activity.
The HIDE_OVERLAY_WINDOWS permission (detected in the manifest output) is required to use setHideOverlayWindows on Android 12 (API level 31) and above.