Security

    Preventing Screenshots with FLAG_SECURE on Android (and the iOS Equivalent)

    Side-by-side of an Android screen blocking a screenshot with FLAG_SECURE and an iOS screen blanking sensitive content during capture.

    On Android, FLAG_SECURE blocks OS-level screenshots and screen recording for a window, and it is the official documented control for this. iOS has no direct equivalent: you cannot fully block a screenshot through a public API, so teams use a secure-text-field trick to blank content and detect recording with UIScreen.isCaptured. FLAG_SECURE still works on Android 14 and later and does stop screen recording. Neither platform stops a physical camera or a rooted or jailbroken device, so treat screenshot protection as one layer, not a guarantee.

    Short answer

    Android gives you a real block through FLAG_SECURE, which excludes a window from screenshots, screen recording, casting, and the Recents preview, and it still applies on Android 14 and 15. iOS has no official API to block screenshots; the practical approach is a UITextField with secure entry to blank sensitive views, plus detecting capture with UIScreen.isCaptured to hide content during recording. FLAG_SECURE does prevent screen recording, using the same secure-surface path as screenshots. It is reliable against normal capture but not against a second-device photo, a rooted or jailbroken device, or a patched build, which is why OWASP MASVS treats it as one platform control among several.

    What FLAG_SECURE does on Android

    FLAG_SECURE is a flag you set on an Android window through WindowManager.LayoutParams. When set, the system marks that window's surface as secure and excludes its contents from screenshots, from screen recordings, from non-secure external displays such as casting, and from the thumbnail shown in the Recents view. A screenshot attempt either fails with a security-policy message or captures a black frame.

    The flag is per-window, not per-app, so every Activity, Dialog, or separate window that shows sensitive content needs it individually. Set it before the window renders, in onCreate with getWindow().setFlags using FLAG_SECURE for both the flag and the mask. Applying it through a shared base Activity or helper is the reliable pattern, because the per-window scope is where most real-world gaps appear.

    The iOS side: no direct FLAG_SECURE equivalent

    iOS deliberately does not expose an API that blocks screenshots of arbitrary content, so there is no single call that matches FLAG_SECURE. The closest supported technique is to place sensitive content inside a UITextField configured with secure entry and use its secure layer to render your view, which the system excludes from screen captures. This is a well-known workaround rather than a dedicated screenshot API.

    For screen recording and mirroring, iOS gives you detection rather than a block: UIScreen.isCaptured tells you the screen is being captured, and capturedDidChangeNotification lets you react by hiding sensitive content while capture is active. iOS also offers userDidTakeScreenshotNotification, which fires after a screenshot so you can log or respond, but it cannot prevent the capture. The honest summary is that iOS leans on detect-and-hide where Android offers a real block, which is the single most important difference to design around when your app ships on both platforms.

    Can you screenshot on Android 14+?

    No, not through normal means, when the window has FLAG_SECURE set. On Android 14 and Android 15 the flag behaves as documented: the system blocks the screenshot and shows a security-policy message or captures a black frame. Android did not remove or weaken FLAG_SECURE in these versions, so a standard user cannot capture a protected window.

    The qualifier is important. That guarantee covers the built-in capture paths on a normal, unmodified device. It does not extend to a rooted device, a custom ROM, or a build where the flag has been patched out, and it never applies to someone photographing the screen with another phone. FLAG_SECURE stops ordinary screenshots on current Android while leaving those out-of-band vectors open.

    Does it prevent screen recording?

    On Android, yes. Screen recording and casting use the same secure-surface mechanism as screenshots, so a window with FLAG_SECURE appears black in a recording or a cast. This is the same protection as for still captures, extended to moving images, and it holds on current Android versions.

    On iOS the answer is different: there is no flag that blanks a recording automatically, so you detect capture with UIScreen.isCaptured and hide sensitive content yourself while it is active. In both cases the same limits apply. A rooted or jailbroken device can defeat these controls, and an external camera recording the screen is entirely outside their scope on either platform.

    Is FLAG_SECURE a reliable control?

    FLAG_SECURE is reliable for what it is designed to do, blocking OS-level screen capture on a standard device, and it is not reliable against a motivated attacker. It is the correct Android control to use, but it belongs in a layered design rather than as the only protection for high-value data. The same judgment applies to the iOS detect-and-hide approach, which is weaker still because it reacts rather than blocks.

    Neither control survives a rooted or jailbroken device, a framework hook, or a second device photographing the screen. Treat both as raising the effort required for casual capture, and combine them with rendering no more sensitive data on screen than necessary, which is the OWASP MASVS principle of reducing exposure instead of relying on a single mechanism.

    Android vs iOS screenshot protection

    The two platforms solve this problem differently, and knowing the gap helps you set realistic expectations for each. The table below compares the capabilities directly.

    CapabilityAndroidiOS
    Block screenshotsYes, via FLAG_SECURENo official API; secure-text-field workaround
    Block screen recordingYes, via FLAG_SECUREDetect with UIScreen.isCaptured, then hide
    Detect a screenshot afterwardNo native eventYes, userDidTakeScreenshotNotification
    Hide content in the app switcherCovered by FLAG_SECUREManual, hide on resign-active
    Reliable vs rooted or jailbrokenNoNo

    The core difference is that Android offers a genuine block while iOS offers detection plus a workaround. Plan your protection around that: on Android you can rely on FLAG_SECURE for OS-level capture, while on iOS you accept that a screenshot can happen and design so that the captured content is either blanked or not sensitive.

    Testing and remediation checklist

    Test only your own app, on a device or emulator you control, in an isolated environment, and confirm each sensitive screen behaves as intended. Objection, the Frida-based open-source toolkit, exposes an android ui FLAG_SECURE command to report and toggle the flag on your own app, which helps you find unprotected windows in line with OWASP MASTG guidance. The checklist below covers both platforms.

    CheckActionDone?
    Android sensitive screensSet FLAG_SECURE on every sensitive window[ ]
    iOS sensitive screensWrap content in a secure text field or hide on capture[ ]
    iOS screen recordingObserve UIScreen.isCaptured and blank content[ ]
    BackgroundingHide sensitive content in Recents and the app switcher[ ]
    Verify on deviceAttempt a screenshot and a recording on the test build[ ]

    Two habits do most of the work. First, apply protection through a shared component so no sensitive screen can ship without it, on either platform. Second, re-check after any release that adds screens or dialogs, because a control set once does not extend to windows added later.

    Where this fits in a security scan

    Screenshot protection is one of many platform controls a review should check, alongside permissions, network security, and stored secrets. A screen that shows account details or tokens without FLAG_SECURE on Android, or without a blanking approach on iOS, is exactly the kind of gap that is easy to miss by hand across a large app.

    A scanner like PTKD.com analyzes your mobile app build and reports findings ordered by severity and mapped to OWASP MASVS, so you see platform-control gaps in context rather than one screen at a time. To be clear about the boundary: a scanner shows where protection is missing and where risk is concentrated, but you still set FLAG_SECURE or the iOS equivalent in code and decide which screens need it. Applied where the scan shows it is missing, the control closes the specific gap.

    What to take away

    • Android has a real block in FLAG_SECURE; iOS has no direct equivalent and relies on a secure-text-field workaround plus capture detection.
    • FLAG_SECURE still works on Android 14 and 15 and blocks screen recording as well as screenshots.
    • On iOS you detect capture with UIScreen.isCaptured and hide content, since a screenshot itself cannot be blocked by a public API.
    • Neither platform stops a physical camera or a rooted or jailbroken device, so use screenshot protection as one layer.
    • Test only your own app on an isolated device, and scan with PTKD.com to find screens where the control is missing.
    • #flag_secure
    • #android security
    • #ios security
    • #screenshot protection
    • #owasp masvs

    Frequently asked questions

    Can you screenshot a FLAG_SECURE app on Android 14+?
    No, not through normal means, when the window has FLAG_SECURE set. On Android 14 and 15 the system blocks the screenshot and shows a security-policy message or a black frame. The exceptions are a rooted or hooked device, a build with the flag patched out, or someone photographing the screen with another phone.
    Does FLAG_SECURE prevent screen recording?
    On Android, yes: recording and casting use the same secure-surface mechanism, so a protected window appears black. On iOS there is no automatic block; you detect capture with UIScreen.isCaptured and hide sensitive content yourself. On both platforms a rooted or jailbroken device or an external camera is outside the control's scope.
    Is FLAG_SECURE a reliable security control?
    It is reliable for blocking OS-level screen capture on a standard Android device, which is its purpose, and unreliable against a motivated attacker. It cannot stop a second-device photo, a rooted device, or a patched build. Use it as one layer, and on iOS treat the detect-and-hide approach as weaker still because it reacts rather than blocks.
    What is the iOS equivalent of FLAG_SECURE?
    There is no direct equivalent. iOS does not expose an API to block screenshots of arbitrary content. The closest supported technique is rendering sensitive content through a UITextField with secure entry, whose secure layer the system excludes from captures, combined with UIScreen.isCaptured to hide content during recording and userDidTakeScreenshotNotification to react after a screenshot.
    How do I test screenshot protection responsibly?
    Test only your own app, on a device or emulator you control, in an isolated environment. Manually attempt a screenshot and a recording on each sensitive screen. Objection, the Frida-based toolkit, has an android ui FLAG_SECURE command to report and toggle the flag on your own app, in line with OWASP MASTG guidance for testing your own software.
    Where does screenshot protection fit in a security review?
    It is one platform control among many, alongside permissions, network security, and stored secrets. A sensitive screen without FLAG_SECURE on Android, or without blanking on iOS, is easy to miss by hand. A scanner like PTKD.com (https://ptkd.com) reports findings mapped to OWASP MASVS so you see the gaps in context, then you set the control in code where it is missing.

    Keep reading

    Scan your app in minutes

    Upload an APK, AAB, or IPA. PTKD returns an OWASP-aligned report with copy-paste fixes.

    Try PTKD free