fix: Cross-chain plugin registration reuse
handle_set_plugin() parsed the signed chain_id only to call app_compatible_with_chain_id() and then discarded it. The stored tokenContext kept the plugin name, contract address, and selector but never the chain the registration was signed for. eth_plugin_perform_ init_default() therefore authorized the plugin solely on address + selector match, which let a host preload a valid signed registration for chain A and then route a transaction on chain B through the same plugin UI, masking attacker-controlled calldata behind a familiar review flow. Store the signed chain_id alongside the registration and refuse to activate the plugin when the transaction's chain_id differs. set_external_plugin keeps its chain-unbound semantics (its signed payload contains no chain_id) and is marked explicitly via PLUGIN_CHAIN_ID_ANY; cross-chain protection there requires a protocol change and is left out of scope. (cherry picked from commit b8f41b54e1bd14f0686fa6b44b81b1aad1c14429)
C
Charles-Edouard de la Vergne committed
1fbe852675baebe6e7477912210de4bfc751e09a
Parent: d0fa135
Committed by Alexandre Paillier <alexandre.paillier@ledger.fr>
on 8/25/2026, 3:03:56 PM