fix(core/ethereum): disallow non-zero ETH value on SLIP-24 ERC-20 swaps
What changed, and why it matters
This update fixes a logic flaw in Trezor's Ethereum signing code. When a user was doing an ERC-20 token swap using a SLIP-24 payment request, the device could also be instructed to send native ETH at the same time. That combination is not expected in a normal token swap and could let an attacker trick the user into authorizing an unintended ETH transfer alongside the token swap. The fix now rejects such transactions outright.
Treat as a security fix and include in release notes. Users should upgrade firmware to a version containing this commit. No immediate user action beyond updating is required.
Security signals we found
Missing input validation on native ETH value during ERC-20 SLIP-24 swap
Potential unintended native ETH transfer bundled with token swap
New explicit DataError thrown to block disallowed value
Regression test added for the blocked condition
Changelog entry tagged as security-related
Evidence from the diff
In core/src/apps/ethereum/clear_signing.py, the _handle_transfer path for SLIP-24 payment requests covering ERC-20 transfers previously did not validate msg.value. The patch adds a check: if native_value is non-zero, it raises DataError(“Non-zero ETH value”). A regression test confirms that signing now fails with that exact error when a non-zero ETH value is supplied with an ERC-20 SLIP-24 swap.
Changed components
core/src/apps/ethereum/clear_signing.pyEthereum transaction signing flowSLIP-24 payment request handling for ERC-20 transfersInspect captured patch +15 / −0
### core/.changelog.d/+eth_nonzero_value_slip24.security
@@ -0,0 +1 @@
+Ethereum: Native token transfer blocked for SLIP-24 swaps.
### core/src/apps/ethereum/clear_signing.py
@@ -1496,6 +1496,8 @@ async def _handle_transfer(
# SLIP-24 payment requests for ERC-20 token transfers
assert msg.payment_req is not None
+ if native_value:
+ raise DataError("Non-zero ETH value")
payment_request_verifier.add_output(arg1_raw_value, recipient_addr)
payment_request_verifier.verify()
### tests/device_tests/ethereum/test_signtx.py
@@ -853,3 +853,15 @@ def test_signtx_payment_req_erc20_swap(session: Session):
params,
example_input_data_erc20_swap["result"],
)
+
+ params = example_input_data_erc20_swap["parameters"]
+ params = params | dict(
+ payment_req=_create_payment_request(session, params),
+ # Non-zero ETH value is disallowed
+ )
+ with pytest.raises(TrezorFailure, match="DataError: Non-zero ETH value"):
+ _do_test_signtx(
+ session,
+ params,
+ result={},
+ )Why this scored 70/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.