range check the server supplied minimum relay fee
What changed, and why it matters
This commit adds a safety check on a fee rate value that a Bitcoin server sends to the Sparrow Wallet app. Before, the app would trust and use whatever number the server provided for the minimum relay fee. Now, if that number is negative or unreasonably high, the app ignores it and falls back to a safe built-in default. This protects users from a malicious or buggy server tricking the wallet into using bad fee rates that could delay, overpay, or otherwise mishandle transactions.
Treat as a low-to-moderate security hardening fix. Review whether other server-supplied numeric values (fee estimates, block heights, relay policies) are similarly validated. Consider adding unit tests for negative, zero, extremely high, and boundary fee-rate values. No urgent incident response is indicated unless this is known to be actively exploited.
Security signals we found
Server-supplied numeric value used without validation
Potential fee-rate manipulation by malicious Electrum server
Fallback to safe default on validation failure
Input sanitization for economic/transaction parameter
Evidence from the diff
The patch modifies ElectrumServer.getMinimumRelayFee() to validate the server-supplied minimum relay fee. It converts the BTC/kB value to sat/vB, then checks that the result is non-negative and does not exceed the upper bound of the application’s long fee-rate range (AppServices.getLongFeeRatesRange().getLast()). If the value is out of range, it is logged as a warning and the method returns Transaction.DEFAULT_MIN_RELAY_FEE instead of the server value. This is a server-input validation fix.
Changed components
src/main/java/com/sparrowwallet/sparrow/net/ElectrumServer.javaElectrumServer.getMinimumRelayFee()Transaction fee estimation / minimum relay fee handlingInspect captured patch +6 / −1
### src/main/java/com/sparrowwallet/sparrow/net/ElectrumServer.java
@@ -1150,7 +1150,12 @@ public Double getMinimumRelayFee() throws ServerException {
Double minFeeRateBtcKb = electrumServerRpc.getMinimumRelayFee(getTransport());
if(minFeeRateBtcKb != null) {
long minFeeRateSatsKb = (long)(minFeeRateBtcKb * Transaction.SATOSHIS_PER_BITCOIN);
- return minFeeRateSatsKb / 1000d;
+ double minFeeRate = minFeeRateSatsKb / 1000d;
+ if(minFeeRate >= 0d && minFeeRate <= AppServices.getLongFeeRatesRange().getLast()) {
+ return minFeeRate;
+ }
+
+ log.warn("Server returned an out of range minimum relay fee of " + minFeeRateBtcKb + " BTC/kB, using default");
}
return Transaction.DEFAULT_MIN_RELAY_FEE;Why this scored 50/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.