Skip to content

Parked from #37: debug-gated key import, FLAG_SECURE, and the Android 12+ D2D question #38

Description

@skyphusion-joan

Split out of #37 so closing that issue does not lose them. Both are LOW and both were
verified still present at c91ff04; neither is addressed by the #37 fix PR, and each is
parked for a stated reason rather than missed.

F6 -- exported activity accepts a device key by Intent extra (debug builds)

MainActivity.kt, consumeDebugImport reads pcp_key from the launching Intent and calls
vm.importDeviceKey(key), gated on ApplicationInfo.FLAG_DEBUGGABLE. A Play build cannot
reach it. On a debug build any app on the device can REPLACE the user's device key, and the
beta channel is where debug builds circulate.

Why it is parked rather than fixed. The obvious hardening is a second, independent gate
(BuildConfig.DEBUG as well as the manifest flag), so that failing open needs two
regressions instead of one. That does not compile today: app/build.gradle.kts sets no
buildFeatures { buildConfig = true }, and under AGP 8 the BuildConfig class is not
generated without it. Measured, not assumed. Enabling buildConfig is a build change with a
wider blast radius than the defect, so it wants its own decision.

Alternatives worth weighing when this is picked up: require a signature-level permission on
the receiving path; or drop the Intent affordance and import the key from a file, which the
iOS simulator-smoke path already does.

F7 -- no FLAG_SECURE while shipping a biometric lock

Zero FLAG_SECURE occurrences tree-wide. The app offers a biometric gate, which sets an
at-rest expectation the recents thumbnail does not honour.

Why it is parked rather than fixed. FLAG_SECURE is user-visible: it blocks screenshots
and screen recording for the whole window, which users notice and dislike. Applying it
unconditionally is a product decision, not a defect fix. The defensible shape is to set it
only while the biometric lock is enabled, which is a preference-to-window wiring change and
should be reviewed as a UX change.

Note the lock is UI-state only (MasterKeys.AES256_GCM_SPEC carries no
setUserAuthenticationRequired), which #37 records as a defensible design; the mismatch with
the recents preview is the cheap part.

UNRESOLVED -- device-to-device transfer on Android 12+

Carried over from #37 verbatim because it is still unresolved and cannot be settled by
reading. allowBackup="false" disables cloud backup, but there is no
android:dataExtractionRules, and on API 31+ D2D is governed by that attribute instead. The
device key is safe regardless (Keystore-bound ciphertext, undecryptable on another handset).
What could travel is filesDir/chat-sessions.json, plaintext chat history.

Settling it needs a real D2D transfer between two devices, or a ruling that moving your own
history to your own new phone is intended behaviour.

Refs #37

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions