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.
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.
WindowManagerServicehands the visible composited surface toActivityManagerService’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 tosystem_serverand 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
- Sibling articles:
screen-capture-attacks,overlay-injection - Architecture:
/architecture/runtime-coherence - Glossary:
/glossary— runtime.environment
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.