What changed, and why it matters
This commit changes the Android two-factor authentication setup flow in Electrum's mobile app. Previously, tapping the QR code would open an external authenticator app directly, but on Android this caused Electrum to be killed by the system, losing the user's progress in the setup wizard. The fix simply copies the secret code to the clipboard instead and tells the user to enter or scan it manually. This is a usability/reliability fix, not a security vulnerability patch.
No security action required. This is a usability fix. If re-enabling the external authenticator app launch later, ensure the wizard state can be preserved across Android process death.
Security signals we found
No security-relevant code change: only UI interaction behavior for 2FA setup
Clipboard used as fallback for sharing OTP secret
External URL opening disabled on Android due to OS lifecycle issue, not due to a security flaw in the URL handler
Evidence from the diff
The QML code in ShowConfirmOTP.qml is modified to always call AppController.textToClipboard(plugin.otpSecret) and show a ‘Copied!’ toast, regardless of platform. The previous Android-specific branch that called Qt.openUrlExternally(qrdata) is commented out, with an explanatory TODO noting the app-killing issue. The instructional label text is updated accordingly. No cryptographic, authentication, or permission logic is changed.
Changed components
electrum/plugins/trustedcoin/qml/ShowConfirmOTP.qmlInspect captured patch +11 / −7
diff --git a/electrum/plugins/trustedcoin/qml/ShowConfirmOTP.qml b/electrum/plugins/trustedcoin/qml/ShowConfirmOTP.qml
index a63d8ec..8b2f818 100644
--- a/electrum/plugins/trustedcoin/qml/ShowConfirmOTP.qml
+++ b/electrum/plugins/trustedcoin/qml/ShowConfirmOTP.qml
@@ -42,12 +42,16 @@ WizardComponent {
render: plugin.otpSecret
onClicked: {
if (plugin.otpSecret) {
- if (AppController.isAndroid()) {
- Qt.openUrlExternally(qrdata)
- } else {
- AppController.textToClipboard(plugin.otpSecret)
- toaster.show(this, qsTr('Copied!'))
- }
+ AppController.textToClipboard(plugin.otpSecret)
+ toaster.show(this, qsTr('Copied!'))
+ // On Android the app will get killed when switching to the authenticator app,
+ // losing the wizard state. TODO: re-enable once we have means to keep app alive in background.
+ // if (AppController.isAndroid()) {
+ // Qt.openUrlExternally(qrdata)
+ // } else {
+ // AppController.textToClipboard(plugin.otpSecret)
+ // toaster.show(this, qsTr('Copied!'))
+ // }
}
}
}
@@ -78,7 +82,7 @@ WizardComponent {
Layout.fillWidth: true
visible: !otpVerified && plugin.otpSecret
wrapMode: Text.Wrap
- text: qsTr('Tap the QR code to open in your authenticator app, or scan it manually. Then authenticate below')
+ text: qsTr('Enter or scan into authenticator app. Then authenticate below')
}
Label {
Why this scored 19/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.