What changed, and why it matters
This commit adds a user-interface check in Electrum's newer QML (mobile-style) interface to make sure a server address typed by the user looks valid before allowing them to continue. It mirrors a similar check that already existed in the older Qt desktop interface. The change prevents users from accidentally saving or connecting to a clearly malformed server address, which could otherwise lead to connection failures or, in worst-case scenarios, being tricked into connecting to an attacker-controlled server.
Treat as a low-severity hardening improvement. No urgent action required, but ensure the validation regex/parser covers all expected server address formats and edge cases (e.g., IPv6, onion, port-only variants).
Security signals we found
Input validation added for user-supplied server address
UI control state now tied to validation result
Wizard progression blocked on invalid input
Mirrors existing Qt GUI validation behavior
No server-side or network protocol changes
Evidence from the diff
The patch exposes a new QML-callable method QENetwork.isValidServerAddress() backed by ServerAddr.from_str_with_inference(). It wires the result into ServerConfig.qml as an addressValid property, disables the OK button in ServerConfigDialog.qml and blocks wizard progression in WCServerConfig.qml when the address is invalid, and clears the address field when switching to Autoconnect. This is a client-side input-validation hardening change for the QML GUI only.
Changed components
electrum/gui/qml/components/ServerConfigDialog.qmlelectrum/gui/qml/components/controls/ServerConfig.qmlelectrum/gui/qml/components/wizard/WCServerConfig.qmlelectrum/gui/qml/qenetwork.pyInspect captured patch +32 / −1
diff --git a/electrum/gui/qml/components/ServerConfigDialog.qml b/electrum/gui/qml/components/ServerConfigDialog.qml
index 80cc54a..9fed629 100644
--- a/electrum/gui/qml/components/ServerConfigDialog.qml
+++ b/electrum/gui/qml/components/ServerConfigDialog.qml
@@ -39,6 +39,7 @@ ElDialog {
FlatButton {
Layout.fillWidth: true
text: qsTr('Ok')
+ enabled: serverconfig.addressValid
icon.source: '../../icons/confirmed.png'
onClicked: {
let auto_connect = serverconfig.serverConnectMode == ServerConnectModeComboBox.Mode.Autoconnect
diff --git a/electrum/gui/qml/components/controls/ServerConfig.qml b/electrum/gui/qml/components/controls/ServerConfig.qml
index 47bd4e6..aae493b 100644
--- a/electrum/gui/qml/components/controls/ServerConfig.qml
+++ b/electrum/gui/qml/components/controls/ServerConfig.qml
@@ -12,6 +12,7 @@ Item {
property bool showAutoselectServer: true
property alias address: address_tf.text
property alias serverConnectMode: server_connect_mode_cb.currentValue
+ property alias addressValid: address_tf.valid
implicitHeight: rootLayout.height
@@ -28,6 +29,11 @@ Item {
ServerConnectModeComboBox {
id: server_connect_mode_cb
+ onCurrentValueChanged: {
+ if (currentValue == ServerConnectModeComboBox.Mode.Autoconnect) {
+ address_tf.text = ""
+ }
+ }
}
Item {
@@ -63,6 +69,26 @@ Item {
enabled: server_connect_mode_cb.currentValue != ServerConnectModeComboBox.Mode.Autoconnect
width: parent.width
inputMethodHints: Qt.ImhNoPredictiveText
+
+ property bool valid: true
+
+ function validate() {
+ if (!enabled) {
+ valid = true
+ return
+ }
+ valid = Network.isValidServerAddress(address_tf.text)
+ }
+
+ onTextChanged: validate()
+ onEnabledChanged: validate()
+
+ Rectangle {
+ anchors.fill: parent
+ color: "red"
+ opacity: 0.2
+ visible: !parent.valid
+ }
}
}
diff --git a/electrum/gui/qml/components/wizard/WCServerConfig.qml b/electrum/gui/qml/components/wizard/WCServerConfig.qml
index bc784d1..b0ab170 100644
--- a/electrum/gui/qml/components/wizard/WCServerConfig.qml
+++ b/electrum/gui/qml/components/wizard/WCServerConfig.qml
@@ -5,7 +5,7 @@ import QtQuick.Controls
import "../controls"
WizardComponent {
- valid: true
+ valid: sc.addressValid
last: true
title: qsTr('Server')
diff --git a/electrum/gui/qml/qenetwork.py b/electrum/gui/qml/qenetwork.py
index b25712d..fa08882 100644
--- a/electrum/gui/qml/qenetwork.py
+++ b/electrum/gui/qml/qenetwork.py
@@ -206,6 +206,10 @@ class QENetwork(QObject, QtEventListener):
def server(self):
return self._server
+ @pyqtSlot(str, result=bool)
+ def isValidServerAddress(self, server: str) -> bool:
+ return ServerAddr.from_str_with_inference(server) is not None
+
@pyqtSlot(str, bool, bool)
def setServerParameters(self, server_str: str, auto_connect: bool, one_server: bool):
net_params = self.network.get_parameters()
Why this scored 30/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.