fix(seed): block screenshots on the verify-seed screen#619
fix(seed): block screenshots on the verify-seed screen#619joshuakrueger-dfx wants to merge 4 commits into
Conversation
Why this PR shows a red ✗ (it is not this change)The functional checks for this PR pass: Analyze & Test ✅, Coverage Floor Gate ✅, BitBox quirks audit ✅. The red is the Visual Regression job, and it is a pre-existing baseline drift, not caused by this PR. It fails on exactly one golden: Evidence that it is unrelated to this change:
Resolution: the drifted baseline needs to be regenerated via the |
|
Per global repo convention (
Two things to drop before merge:
Separate scope note: this PR actually closes #612 S3 ("VerifySeedPage has no screenshot protection at all"), not #612 S1 ("Seed phrase leaks to OS app-switcher / no Fix itself looks correct for the S3 gap. |
|
Re API as Decision Authority ( No API involvement — this is a pure-client device-policy concern. |
|
@TaprootFreak done — dropped the |
Visual Regression fixThe red VR here was not the shared HomePage baseline drift — it was a real gap introduced by this PR. The two Root cause: converting Fix (commit |
|
Repo-rule compliance (commit |
Status — ready for review
Open gates: formal maintainer approval ( |
VerifySeedView was a StatelessWidget with no screenshot protection, unlike the sibling seed screens (create_wallet_view, settings_seed_view). The user enters real seed words here, so they could land in the OS app-switcher snapshot or a screen recording. Convert to StatefulWidget and disable screenshots on init / re-enable on dispose, matching the sibling screens. Adds a widget test asserting the no_screenshot channel receives screenshotOff on init and screenshotOn on dispose. (Native app-switcher blanking itself is not unit-testable; this pins the contract the protection relies on.) Refs RealUnitCH#612 (S1)
The golden harness rendered VerifySeedView without mocking the com.flutterplaza.no_screenshot_methods channel, so the screenshotOff() call in initState threw MissingPluginException and the goldens could not even be generated. Stub the channel (as the widget test already does).
Per CONTRIBUTING.md, platform-specific code paths must carry the // @no-integration-test annotation while no integration_test/ dir exists.
604cf31 to
7afd40e
Compare
Summary
VerifySeedView(where the user re-enters real seed words) was aStatelessWidgetwith no screenshot protection, unlike the sibling seed screens (create_wallet_view.dart,settings_seed_view.dart). So the entered words could be captured in the OS app-switcher thumbnail or a screen recording.Fix: convert
VerifySeedViewto aStatefulWidgetand callNoScreenshot.instance.screenshotOff()ininitState/screenshotOn()indispose— exactly the pattern the two sibling seed screens already use (so non-sensitive screens stay screenshot-able).Test
Widget test (in the existing
verify_seed_page_test.dart) asserting theno_screenshotmethod channel receivesscreenshotOffon init andscreenshotOnon dispose. Native app-switcher blanking is not unit-testable in Flutter; this pins the contract the protection relies on (on-device recents/recording check remains a manual sign-off).Verification (local, CI-equivalent, Flutter 3.41.6)
flutter analyzeon the changed files: No issues found.screenshotOffcall), confirming it catches the regression.Scope
Addresses the S3 item of #612 ("VerifySeedPage has no screenshot protection at all").
This does not close S1 ("Seed phrase leaks to OS app-switcher / no
FLAG_SECURE"): S1 needsFLAG_SECUREonMainActivity.ktto cover the Android recents/app-switcher thumbnail and screen-recording vector app-wide, which this PR does not touch.