What changed, and why it matters
This change makes the two-factor authentication (2FA) QR code in Electrum's mobile/QML interface clickable. On Android, tapping the QR code opens the authenticator app directly with the setup link; on other platforms it copies the secret to the clipboard. It is a small usability improvement, not a security fix. There is no direct evidence of malicious intent or a vulnerability, but it does slightly increase the attack surface by invoking an external app and by copying a sensitive OTP secret to the system clipboard.
Review as a normal usability commit. If security hardening is desired, consider confirming the target app before opening the otpauth:// URI, restricting clipboard exposure of the OTP secret, and documenting the behavior for users. No immediate patch or incident response is indicated by this diff alone.
Security signals we found
New external URL invocation path (Qt.openUrlExternally) for otpauth:// URI
Sensitive TOTP secret copied to system clipboard on non-Android platforms
QRImage control now emits a generic clicked() signal consumed by parent components
No input validation or sanitization changes visible in the diff
No security-relevant commit message or vendor disclosure
Evidence from the diff
The commit adds a clicked() signal to the reusable QRImage.qml control and wires it in ShowConfirmOTP.qml. When the user taps the 2FA setup QR code, the app either calls Qt.openUrlExternally(qrdata) on Android (launching the otpauth:// URI in the default authenticator app) or copies the raw TOTP secret to the clipboard via AppController.textToClipboard(). The QR code data itself already contained the secret, so the change does not expose new information; it only changes how that information is handed off. The external-URL and clipboard paths are standard OS mechanisms, but they introduce minor trust boundaries: another app could register for otpauth:// URIs, and clipboard contents are accessible to other apps on some platforms.
Changed components
electrum/gui/qml/components/controls/QRImage.qmlelectrum/plugins/trustedcoin/qml/ShowConfirmOTP.qmlTrustedcoin 2FA setup wizard (QML/Android builds)Inspect captured patch +15 / −1
diff --git a/electrum/gui/qml/components/controls/QRImage.qml b/electrum/gui/qml/components/controls/QRImage.qml
index 46929ea..ce8ac71 100644
--- a/electrum/gui/qml/components/controls/QRImage.qml
+++ b/electrum/gui/qml/components/controls/QRImage.qml
@@ -8,6 +8,8 @@ Item {
property bool enableToggleText: false // if true, clicking the QR code shows the encoded text
property bool isTextState: false // internal state, if the above is enabled
+ signal clicked()
+
property var _qrprops: QRIP.getDimensions(qrdata)
width: r.width
@@ -71,6 +73,8 @@ Item {
onClicked: {
if (enableToggleText) {
root.isTextState = !root.isTextState
+ } else {
+ root.clicked()
}
}
}
diff --git a/electrum/plugins/trustedcoin/qml/ShowConfirmOTP.qml b/electrum/plugins/trustedcoin/qml/ShowConfirmOTP.qml
index b99ab97..a63d8ec 100644
--- a/electrum/plugins/trustedcoin/qml/ShowConfirmOTP.qml
+++ b/electrum/plugins/trustedcoin/qml/ShowConfirmOTP.qml
@@ -40,6 +40,16 @@ WizardComponent {
qrdata: encodeURI('otpauth://totp/Electrum 2FA ' + wizard_data['wallet_name']
+ '?secret=' + plugin.otpSecret + '&digits=6')
render: plugin.otpSecret
+ onClicked: {
+ if (plugin.otpSecret) {
+ if (AppController.isAndroid()) {
+ Qt.openUrlExternally(qrdata)
+ } else {
+ AppController.textToClipboard(plugin.otpSecret)
+ toaster.show(this, qsTr('Copied!'))
+ }
+ }
+ }
}
Item {
@@ -68,7 +78,7 @@ WizardComponent {
Layout.fillWidth: true
visible: !otpVerified && plugin.otpSecret
wrapMode: Text.Wrap
- text: qsTr('Enter or scan into authenticator app. Then authenticate below')
+ text: qsTr('Tap the QR code to open in your authenticator app, or scan it manually. Then authenticate below')
}
Label {
Why this scored 22/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.