Security

    Bypass Screenshot Defenses: Can Attackers Defeat View Once APIs?

    A view-once message protected by FLAG_SECURE showing black in a screen-mirroring session while a second phone camera photographs the screen.

    View-once and screenshot defenses are deterrents, not guarantees, so an app cannot truly stop someone from capturing content they are allowed to see. On Android, the FLAG_SECURE window flag is the native way to block screenshots, screen recording, and casting to non-secure displays, so a screen-mirroring tool like Zoom shows a protected window as black. But a rooted device can strip that protection, and no software control closes the analog hole: a second camera photographing the screen defeats every screenshot API. If you are building a view-once feature, treat it as friction that reduces casual saving, not as a boundary that keeps sensitive content from leaking.

    Short answer

    You cannot technically prevent a determined viewer from capturing content they can see, so view-once is deterrence, not protection. Per Android's FLAG_SECURE reference, that flag blocks screenshots, recording, and casting to non-secure displays, so screen mirroring shows a protected window as black. iOS has no equivalent prevention, only detection through signals like screenshot notifications and a captured-screen indicator. A rooted or otherwise compromised device can bypass these client-side blocks, and per the OWASP MASVS, such controls raise cost but do not replace real protection. The content the viewer can see can always be photographed with another camera, which no API closes.

    What view-once and screenshot defenses actually promise

    View-once and screenshot defenses promise to reduce easy, casual copying, not to make content uncopyable. A view-once message or an app screen with screenshot blocking makes it harder to save content in the obvious ways: tapping the screenshot buttons, screen recording, or casting. That deters an ordinary user from idly keeping a copy, which is a real and useful effect for many products, and it is what these features are actually good at.

    What they do not promise, despite how they are often marketed, is that content the recipient can view cannot be captured. Any content rendered on a screen the viewer controls is, by definition, visible to that viewer, and visibility is capturability with enough determination. So the honest promise is friction and deterrence: fewer casual copies, a signal that copying is not intended, and a higher effort bar. Treating that promise as a guarantee is where security designs go wrong, because a motivated viewer has options no app can remove.

    What API disables screenshots natively?

    On Android, the native mechanism is the FLAG_SECURE window flag, set through the window's layout parameters, which tells the system to exclude that window's content from screenshots, from screen recordings, and from display on non-secure external outputs. It is the correct tool for marking a sensitive screen so the platform blocks the common capture paths, and it works at the window level rather than requiring you to detect and react to each attempt.

    iOS is different: there is no public API that outright prevents a screenshot or screen recording. Instead, iOS offers detection. Your app can be notified when the user takes a screenshot and can check whether the screen is being captured or recorded, then react by obscuring content, but it cannot stop the capture from happening. So the accurate answer is that Android has a native prevention flag in FLAG_SECURE, while iOS provides detection signals you respond to, not prevention. Neither platform can prevent a photograph of the screen by another device.

    Does Zoom screen mirroring bypass the app blocks?

    Screen mirroring and screen sharing, such as sharing your screen in Zoom, do not bypass FLAG_SECURE on Android, because that flag also excludes the window from casting and from non-secure displays. A window marked secure appears blank or black to the mirroring or sharing session, so the remote viewers see nothing where the protected content is. In that sense, the app block holds against ordinary screen sharing, which is one of its intended purposes.

    The caveats matter, though. This only works when the app actually applies FLAG_SECURE to the relevant window, and it assumes an unmodified device; a rooted environment can defeat it, as below. It also does nothing about the analog hole, since the person on the Zoom call could simply point a phone camera at their own screen and record what they see. So screen mirroring is blocked by the flag on a normal device, but blocking mirroring is not the same as protecting the content, because the viewer still has ways to capture what is in front of them.

    The impact of a rooted environment

    A rooted or otherwise compromised device changes the picture, because at that level the protections your app relies on can be removed. Screenshot blocking through FLAG_SECURE is enforced by the platform, and root access sits below the platform, so a rooted device can use modules or instrumentation to strip the secure flag, capture the framebuffer directly, or otherwise ignore the block. The same applies to iOS detection on a jailbroken device, where the signals your app depends on can be suppressed.

    This is the same structural point that governs all client-side protection: on a device the attacker fully controls, controls that run on that device can be neutralized. For a view-once or screenshot defense, root means the block is not merely bypassable through the analog hole but removable outright, so the content can be captured silently and at full fidelity. When you assess your feature, assume that a determined attacker can and will use a compromised device, and design so that this does not expose anything you cannot afford to lose.

    The analog hole: the limit no API closes

    The analog hole is the reason no screenshot API can ever fully protect visible content: a separate camera can photograph or film the screen, and nothing on the device is involved to block. Whatever a viewer can see, they can point another phone at and record, capturing the content without touching the app, the operating system, or any flag you set. This is not a bug to be patched; it is a consequence of the content being displayed at all.

    Because the analog hole is unclosable, it sets the ceiling on what view-once and screenshot defenses can achieve. They can stop the easy digital capture paths and deter casual saving, but they cannot beat a camera. Any design that assumes ephemeral content is truly gone, or that a screenshot block makes content safe, is ignoring this limit. The realistic goal is to make capture inconvenient and traceable enough that most users do not bother, while accepting that a determined one always can, and planning for the consequences of that rather than pretending it is impossible.

    What this means if you are building view-once

    If you are building a view-once or disappearing-content feature, design it as a deterrent and a signal, not as a protection guarantee, and be honest with users about that. Use screenshot blocking and detection to reduce casual copying and to indicate that saving is not intended, which meets the reasonable expectations of most users. What you should not do is promise, or internally assume, that content sent to a recipient cannot be kept, because that promise is not one any client-side feature can keep.

    The security consequence follows directly: do not send anything through a view-once feature that would cause real harm if captured, because you cannot ensure it will not be. If content must never leak, the answer is not a better screenshot block; it is not putting that content on an untrusted client in a viewable form at all. View-once is appropriate for reducing friction and setting norms around ordinary content, and inappropriate as the sole control over anything whose exposure you cannot tolerate.

    Remediation: deterrence, detection, and server-side control

    Effective remediation layers deterrence and detection on the client with real control on the server. On the client, apply FLAG_SECURE to sensitive Android screens and use iOS capture detection to obscure content or warn the user, which handles the casual cases well. Add visible or invisible watermarking tied to the viewer, so that if content does leak, the capture can be traced back, which deters intentional copying more than a block alone.

    The real protection, though, lives server-side and in what you choose to expose. Keep secrets and high-value data on the server and never deliver them to a client in a form that must not be captured; enforce access with server-side authorization so the deciding check is not on the device; and for media that genuinely needs protection, use established DRM rather than a homegrown screenshot block, while recognizing even DRM does not beat a camera. The principle throughout is to assume the client can be compromised and to protect what matters where the attacker does not have control.

    Protection layers and their limits

    Seeing the layers and what defeats each clarifies where to place trust. The table below compares them.

    LayerWhat it blocksWhat defeats it
    FLAG_SECURE on AndroidScreenshots, recording, casting to non-secure displaysA rooted device, and a second camera
    iOS capture detectionNothing directly; it only notifies youAn attacker who ignores the signal
    View-once or ephemeral UICasual re-viewing and easy savingScreenshot, mirroring, or a camera
    Server-side control and DRMUnauthorized access to the source contentContent still visible can be filmed

    Read the table top to bottom: client-side layers reduce casual capture, while only keeping content off the untrusted client actually protects it, and even then the analog hole remains.

    Design checklist

    Working through these steps aligns your feature with what is actually achievable. The checklist below covers them.

    StepActionDone?
    Set honest expectationsTreat view-once as deterrence, not a guarantee[ ]
    Apply FLAG_SECUREBlock screenshots on sensitive Android screens[ ]
    Detect on iOSReact to screenshot and recording signals[ ]
    Assume root defeats itDo not rely on client capture blocks for real secrets[ ]
    Keep secrets server-sideDo not deliver what must never leak to the client[ ]
    Add watermarkingTrace leaks and deter intentional capture[ ]

    The step that matters most is keeping genuine secrets off the untrusted client, because every client-side block above it can be defeated by root or a camera.

    Assess what your app exposes

    Because the real question is what your app puts in front of an untrusted client, it helps to see what your build actually exposes rather than assume a screenshot block covers it. Knowing where sensitive data is stored, whether sensitive screens set FLAG_SECURE, and what secrets ship in the app is the input to a realistic design.

    A scanner like PTKD.com analyzes your build and reports issues such as insecure data storage, leaked keys and secrets, and over-broad permissions by severity, mapped to OWASP MASVS, so you can see what would be exposed if a client-side defense is bypassed. To be clear about the boundary: PTKD does not make screenshots or screen capture impossible, which nothing can, and it does not implement view-once. It helps you understand and reduce what your app exposes so you are not relying on a defeatable block to protect it.

    What to take away

    • View-once and screenshot defenses are deterrents that reduce casual copying, not guarantees that visible content cannot be captured.
    • Android's native prevention is the FLAG_SECURE window flag, which also blocks screen mirroring and casting, while iOS offers only capture detection, not prevention.
    • Screen sharing like Zoom is blocked by FLAG_SECURE on a normal device, but a rooted device can strip the protection and a second camera defeats any block.
    • The analog hole means no API can protect content a viewer can see, so never send through view-once anything whose capture you cannot tolerate.
    • Layer client deterrence and detection with server-side control and watermarking, and assess what your app exposes with a tool like PTKD.com.
    • #view once
    • #flag_secure
    • #screenshot protection
    • #owasp masvs
    • #mobile security

    Frequently asked questions

    Can an app really stop screenshots of view-once content?
    No. View-once and screenshot defenses reduce casual copying but cannot stop a determined viewer from capturing content they can see. Any content rendered on a screen the viewer controls is visible, and visibility is capturability with enough effort. These features deter idle saving and signal that copying is not intended, which is genuinely useful, but treating them as a guarantee that content cannot be kept is where designs go wrong.
    What API disables screenshots natively?
    On Android, the FLAG_SECURE window flag, set through the window's layout parameters, tells the system to exclude that window from screenshots, screen recordings, and non-secure external displays. It is the native prevention mechanism. iOS has no public API that prevents a screenshot or recording; it provides detection instead, notifying your app of a screenshot and letting it check whether the screen is captured so it can obscure content. Neither can prevent a photograph by another device.
    Does Zoom screen mirroring bypass the app's screenshot blocks?
    Not on a normal Android device, because FLAG_SECURE also excludes the window from casting and non-secure displays, so a shared or mirrored session shows the protected window as blank or black. That holds only when the app actually applies the flag and the device is unmodified. It does nothing about the analog hole, since the person sharing could point a phone camera at their own screen, and a rooted device can strip the protection entirely.
    How does a rooted device affect screenshot protection?
    It can remove it. FLAG_SECURE is enforced by the platform, and root access sits below the platform, so a rooted device can use modules or instrumentation to strip the secure flag, capture the framebuffer directly, or ignore the block, and a jailbroken iOS device can suppress capture-detection signals. On a device the attacker fully controls, client-side controls can be neutralized, so root means the content can be captured silently at full fidelity.
    Should I build a view-once feature at all?
    Yes, as a deterrent and a signal, not as a protection guarantee, and be honest with users about that. Use screenshot blocking and detection to reduce casual copying and indicate saving is not intended, which meets most users' expectations. What you should not do is send anything through it that would cause real harm if captured, because no client-side feature can ensure it will not be. For content that must not leak, do not put it on an untrusted client in viewable form.
    What actually protects sensitive content then?
    Server-side control and choosing what to expose. Keep secrets and high-value data on the server, enforce access with server-side authorization so the deciding check is not on the device, and deliver to the client only what can safely be seen. Add viewer-tied watermarking to trace and deter intentional leaks, and use established DRM for media that needs it, while recognizing even DRM does not beat a camera. Assume the client can be compromised and protect what matters where the attacker has no control.

    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