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
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 isparked for a stated reason rather than missed.
F6 -- exported activity accepts a device key by Intent extra (debug builds)
MainActivity.kt,consumeDebugImportreadspcp_keyfrom the launching Intent and callsvm.importDeviceKey(key), gated onApplicationInfo.FLAG_DEBUGGABLE. A Play build cannotreach 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.DEBUGas well as the manifest flag), so that failing open needs tworegressions instead of one. That does not compile today:
app/build.gradle.ktssets nobuildFeatures { buildConfig = true }, and under AGP 8 theBuildConfigclass is notgenerated without it. Measured, not assumed. Enabling
buildConfigis a build change with awider 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_SECUREwhile shipping a biometric lockZero
FLAG_SECUREoccurrences tree-wide. The app offers a biometric gate, which sets anat-rest expectation the recents thumbnail does not honour.
Why it is parked rather than fixed.
FLAG_SECUREis user-visible: it blocks screenshotsand 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_SPECcarries nosetUserAuthenticationRequired), which #37 records as a defensible design; the mismatch withthe 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 noandroid:dataExtractionRules, and on API 31+ D2D is governed by that attribute instead. Thedevice 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