YinkoShield

Knowledge Center / Mobile runtime attacks / mobile runtime attacks · 2026·01

Snapshot timing — exploiting visible state during background transition

When an Android activity transitions to the background, the platform captures a thumbnail of its visible state. The thumbnail is shown in the Recents / Overview screen and persists on disk. If the activity was rendering sensitive content — a PIN, a one-time code, a partially-typed password — and the developer did not set FLAG_SECURE on the window, the snapshot captures it. The interval between the user pressing home and the snapshot being written is short — typically under a second — but it is enough.

[ snapshot timing — task-switch screenshot ] onResume user types PIN home press onPause SNAPSHOT taken by ActivityManager onStop activity backgrounded captured frame stored in /data/system/recent_*.jpg until next foreground visible in Recents / Overview contains: PIN entry visible FLAG_SECURE window.addFlags( FLAG_SECURE) when set: · no recents snapshot · no MediaProjection · no screenshots absent if app forgot
The platform captures a screenshot of the activity for the recents thumbnail at the moment of background transition. Without FLAG_SECURE on sensitive activities, the snapshot includes whatever was on screen.

1. Mechanism

Android’s WindowManagerService / TaskSnapshotController (with AMS triggering the transition) captures a thumbnail of the top activity at the moment of background transition [2] and persists it to disk under /data/system_ce/<userId>/snapshots/ — the path used by TaskSnapshotPersister from Android 9 (Pie) onwards. The thumbnail is used by the Recents screen and is retained until the activity comes back to the foreground or the snapshot is evicted.

The capture timing relative to the lifecycle is implementation- dependent — AOSP captures around the window animation transition that follows onPause(), but the exact ordering between onPause and onStop can vary by OEM. The window is in any case short enough that the activity’s last-rendered frame is what the platform writes; the JPEG composites whatever was on screen at that moment.

The exploit class is straightforward: wherever a developer renders sensitive content — passcode entry, one-time code display, partial-password fields, transaction details — and does not set FLAG_SECURE on the window [1], an attacker with file-system read access (rooted device, side-loaded module, file-system exploit) can recover that content from the persisted snapshot.

2. Where in the runtime it operates

Two surfaces:

  • The thumbnail capture pipeline. WindowManagerService hands the visible composited surface to ActivityManagerService’s task-snapshot subsystem, which writes the JPEG.
  • The persisted snapshot files. Located under /data/system_ce/<userId>/snapshots/ (CE-encrypted under the user’s credential key, accessible to system_server and to anything with appropriate platform privileges; readable to rooted attackers, file-system exploits, or side-loaded modules with elevated context).

The protection is WindowManager.LayoutParams.FLAG_SECURE [1]. When set on a window, the platform skips the snapshot, blocks MediaProjection capture of that window, and prevents screenshot of that window via the platform shortcut. The flag must be set per-window — typically inside Activity.onCreate() before the first inflation — and is easy to forget on activities that didn’t exist when the security review happened.

3. Which checkpoints it bypasses

  • Play Integrity / App Attest. The capture is platform behaviour; nothing about the device or the calling app is unhealthy.
  • FIDO2 / EMV. These checkpoints don’t observe the screen.
  • Hardware attestation. Unrelated; the capture is an application-policy issue, not a key-provenance one.

The snapshot pipeline is part of how Android’s task switching works. It is not a vulnerability in the platform; the vulnerability sits in apps that fail to opt out for sensitive activities.

4. Which signals make it observable

runtime.environment. The Trusted Runtime Primitive observes the activity-window flags at sensitive moments and can flag when an activity that should be marked FLAG_SECURE has the flag missing. In practice the substrate emits the window_flag_secure value at the moment of credential entry or transaction confirmation; the operator’s verifier reads the value and decides whether to permit the action.

5. Evidence Token shape when observed

The following example is illustrative; field names, type values, and schema are defined in YEI-001 §4 (available through the spec-access process).

{
  "ev": [{
    "ts":   "2026-06-15T10:23:14Z",
    "class": "runtime.environment",
    "type":  "window.flag_secure",
    "data": {
      "activity":     "com.bank.app.PinEntryActivity",
      "flag_secure":  false,
      "during":       "credential_entry"
    }
  }]
}

When flag_secure is false during a credential or transaction event, the operator’s verifier can refuse, prompt for an alternative method, or signal the integration team — depending on policy. This is also a signal a defending team can wire to their internal policy assistant: any activity that handles sensitive content should set FLAG_SECURE, and Execution Evidence Infrastructure (EEI) — the device-identity infrastructure layer for banking and payments — emitting flag_secure: false on a sensitive activity is a regression marker the operator can act on directly.

6. Cross-references

7. External references

[1] Android Developers. WindowManager.LayoutParams.FLAG_SECURE. developer.android.com/reference/android/view/WindowManager.LayoutParams#FLAG_SECURE. Cited 2026-01-13.

[2] AOSP. TaskSnapshotController and TaskSnapshotPersister (/data/system_ce/<userId>/snapshots/ since Android 9 / Pie). cs.android.com/android/platform/superproject/main/+/main:frameworks/base/services/core/java/com/android/server/wm/TaskSnapshotController.java. Cited 2026-01-13.

[3] OWASP MASTG. Screen-related Data Leakage. mas.owasp.org/MASTG/Android/0x05d-Testing-Data-Storage/. Cited 2026-01-13.