What changed, and why it matters
This commit updates the Trezor Python library so it no longer tries to auto-detect a newer device protocol by sending a test message to every bridge-based device it finds. Instead, it now trusts the reported bridge version number to decide whether the newer protocol (THP/V2) is supported. The removed detection logic could briefly open a connection and send an Initialize message to each device during enumeration, which might cause minor side effects or confusion, but it is not a clear-cut security vulnerability.
Treat as a routine cleanup/fix. Review whether dropping runtime protocol detection could cause the library to select the wrong protocol against very new or misreporting bridge versions; if so, add explicit protocol negotiation at connection time rather than reintroducing silent probing.
Security signals we found
Removed runtime protocol probing that opened every bridge transport and sent an Initialize message
Enumeration now relies solely on a version-number threshold to decide THP support
No input validation changes, no cryptographic changes, no privilege changes
Evidence from the diff
The patch removes detect_protocol_version(), _is_transport_valid(), and filter_invalid_bridge_transports() from python/src/trezorlib/transport/bridge.py. It also removes the import of ProtocolVersion and stops filtering bridge transports during enumeration. The bridge version threshold for THP support is updated from a placeholder (2,0,31) to (3,1,0) with a reference to a Trezor Suite commit. The change simplifies transport enumeration to rely on version gating rather than runtime probing.
Changed components
python/src/trezorlib/transport/bridge.pyTrezor Python client library bridge transport enumerationInspect captured patch +5 / −42
diff --git a/python/src/trezorlib/transport/bridge.py b/python/src/trezorlib/transport/bridge.py
index 223383f4f..7bdc6ab81 100644
--- a/python/src/trezorlib/transport/bridge.py
+++ b/python/src/trezorlib/transport/bridge.py
@@ -22,7 +22,6 @@ import typing as t
import requests
from typing_extensions import Self
-from ..client import ProtocolVersion
from ..log import DUMP_PACKETS
from . import DeviceIsBusy, Transport, TransportException
@@ -35,7 +34,8 @@ TREZORD_HOST = "http://127.0.0.1:21325"
TREZORD_ORIGIN_HEADER = {"Origin": "https://python.trezor.io"}
TREZORD_VERSION_MODERN = (2, 0, 25)
-TREZORD_VERSION_THP_SUPPORT = (2, 0, 31) # TODO add correct value
+# https://github.com/trezor/trezor-suite/commit/4881cefcd4aec9f4da44220cf5ee4c79fd5eb3ff
+TREZORD_VERSION_THP_SUPPORT = (3, 1, 0)
CONNECTION = requests.Session()
CONNECTION.headers.update(TREZORD_ORIGIN_HEADER)
@@ -72,40 +72,6 @@ def supports_protocolV2() -> bool:
return get_bridge_version() >= TREZORD_VERSION_THP_SUPPORT
-def detect_protocol_version(transport: "BridgeTransport") -> int:
- from .. import mapping, messages
- from ..messages import FailureType
-
- protocol_version = ProtocolVersion.V1
- request_type, request_data = mapping.DEFAULT_MAPPING.encode(messages.Initialize())
- transport.open()
- transport.write_chunk(request_type.to_bytes(2, "big") + request_data)
- response = transport.read_chunk()
- response_type = int.from_bytes(response[:2], "big")
- response_data = response[2:]
- response = mapping.DEFAULT_MAPPING.decode(response_type, response_data)
- if isinstance(response, messages.Failure):
- if response.code == FailureType.InvalidProtocol:
- LOG.debug("Protocol V2 detected")
- protocol_version = ProtocolVersion.V2
-
- return protocol_version
-
-
-def _is_transport_valid(transport: "BridgeTransport") -> bool:
- is_valid = detect_protocol_version(transport) == ProtocolVersion.V1
- if not is_valid:
- LOG.warning("Detected unsupported Bridge transport!")
- return is_valid
-
-
-def filter_invalid_bridge_transports(
- transports: t.Iterable["BridgeTransport"],
-) -> t.Sequence["BridgeTransport"]:
- """Filters out invalid bridge transports. Keeps only valid ones."""
- return [t for t in transports if _is_transport_valid(t)]
-
-
class BridgeHandle:
def __init__(self, transport: "BridgeTransport") -> None:
self.transport = transport
@@ -200,12 +166,9 @@ class BridgeTransport(Transport):
) -> t.Iterable["BridgeTransport"]:
try:
legacy = is_legacy_bridge()
- return filter_invalid_bridge_transports(
- [
- BridgeTransport(dev, legacy)
- for dev in call_bridge("enumerate").json()
- ]
- )
+ return [
+ BridgeTransport(dev, legacy) for dev in call_bridge("enumerate").json()
+ ]
except Exception:
return []
Why this scored 16/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.