You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PR #20942 correctly suppresses the seed phrase from the accessibility tree (Accessible.ignored). This issue proposes a second gate: detect when an active accessibility service is running and warn the user before they tap Reveal.
An app holding BIND_ACCESSIBILITY_SERVICE can read on-screen content even after #20942 if the user taps Reveal — once the words are user-initiated-revealed, they are intentionally visible. The risk is that the user does not know a third-party app is listening.
Proposed UX
When the user navigates to the seed phrase reveal screen, and before they tap Reveal:
Query the list of enabled, non-system accessibility services
If any are found → show an inline warning banner:
An app with screen reader access is active [App name] can read content on this screen. Make sure you trust this app before revealing your recovery phrase. [Continue anyway][Cancel]
If no third-party accessibility services → proceed normally, no interruption
This is distinct from blocking the reveal — it is an informed-consent step. The user keeps full control.
Implementation sketch (Java + Qt/QML — matching Status codebase pattern)
Android side — Java (following the existing helper pattern in mobile/android/qt6/src/app/status/mobile/):
Expose via JNI from StatusQtActivity.java (same pattern as mainWindowReady(), openDeepLink() etc.):
// In StatusQtActivity.javapublicstaticString[] getThirdPartyA11yServices() {
if (sInstance == null) returnnewString[0];
returnAccessibilityServiceHelper.getActiveThirdPartyServices(sInstance);
}
QML side — call before reveal:
// SeedPhrase.qmlpropertyvaractiveA11yServices: []
Component.onCompleted: {
// Qt.callMethod or existing JNI bridge pattern used in the codebase
activeA11yServices =StatusAndroid.getThirdPartyA11yServices()
}
StatusBanner {
visible:activeA11yServices.length>0
type:StatusBanner.Type.Warning
statusText:qsTr("An app with screen reader access is active: %1. It may be able to read this screen after you reveal your recovery phrase.")
.arg(activeA11yServices.join(", "))
}
Post-reveal, the words are intentionally shown — no suppression is appropriate
Without this warning, a malicious accessibility service (e.g. Crocodilus, SeedSnatcher) could log the words the moment the user taps Reveal, without any indication
This check costs one API call and adds at most one confirmation step for affected users
Summary
PR #20942 correctly suppresses the seed phrase from the accessibility tree (
Accessible.ignored). This issue proposes a second gate: detect when an active accessibility service is running and warn the user before they tap Reveal.An app holding
BIND_ACCESSIBILITY_SERVICEcan read on-screen content even after #20942 if the user taps Reveal — once the words are user-initiated-revealed, they are intentionally visible. The risk is that the user does not know a third-party app is listening.Proposed UX
When the user navigates to the seed phrase reveal screen, and before they tap Reveal:
This is distinct from blocking the reveal — it is an informed-consent step. The user keeps full control.
Implementation sketch (Java + Qt/QML — matching Status codebase pattern)
Android side — Java (following the existing helper pattern in
mobile/android/qt6/src/app/status/mobile/):Expose via JNI from
StatusQtActivity.java(same pattern asmainWindowReady(),openDeepLink()etc.):QML side — call before reveal:
Why this matters
Accessible.ignored(PR fix: exclude seed phrase words from accessibility tree before Reveal tap #20942) protects the pre-reveal tree — correct and necessaryReference
NativeIndicatorHelper.java,SecureAndroidAuthentication.java— same Java helper → JNI bridge architectureisAccessibilityTool()API 31+