What changed, and why it matters
This commit adds a type check to ensure a transaction fee value coming from an external server is either a valid whole number or absent. Without the check, an unexpected type (such as a string or special object) could later cause errors or unusual behavior inside the wallet when it stores or compares fee data. The change is defensive and narrows the range of bad inputs the wallet will accept.
Treat as a defensive hardening commit. Review whether other server-provided fields in the same code path are type-validated, and consider adding schema validation or safe coercion rather than relying solely on assertions, which can be disabled in some Python run modes.
Security signals we found
Type assertion added to server-provided input
Server-trusted data written to wallet database
Missing input validation before patch
Potential type confusion in fee handling
Evidence from the diff
In electrum/wallet_db.py, add_tx_fee_from_server() now asserts fee_sat is None or isinstance(fee_sat, int). The function stores server-reported transaction fees in self.tx_fees and is decorated with @modifier, meaning it writes to the wallet database. Previously only txid was type-checked. An attacker-controlled or malicious Electrum server could supply a non-integer, non-None fee_sat. The downstream effects are not fully visible from this single diff, but the stored value is later used in fee/CPFP/RBF logic and could trigger type confusion, comparison errors, or serialization issues. The patch is a hardening measure rather than a complete fix for a known exploit chain.
Changed components
electrum/wallet_db.pyadd_tx_fee_from_servertx_fees storageserver fee reportingInspect captured patch +1 / −0
diff --git a/electrum/wallet_db.py b/electrum/wallet_db.py
index 2bd6936..c20180a 100644
--- a/electrum/wallet_db.py
+++ b/electrum/wallet_db.py
@@ -1820,6 +1820,7 @@ class WalletDB(JsonDB):
@modifier
def add_tx_fee_from_server(self, txid: str, fee_sat: Optional[int]) -> None:
assert isinstance(txid, str)
+ assert fee_sat is None or isinstance(fee_sat, int)
# note: when called with (fee_sat is None), rm currently saved value
if txid not in self.tx_fees:
self.tx_fees[txid] = TxFeesValue()
Why this scored 32/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.