fix: tolerate malformed large tx deltas#6089
Conversation
|
Welcome to RustChain! Thanks for your first pull request. Before we review, please make sure:
Bounty tiers: Micro (1-10 RTC) | Standard (20-50) | Major (75-100) | Critical (100-150) A maintainer will review your PR soon. Thanks for contributing! |
bitdamii
left a comment
There was a problem hiding this comment.
Approved after focused local validation.
What I checked:
- Confirmed the large_tx formatter no longer crashes when
deltais non-numeric and now renders the safe? RTCfallback. - Confirmed the existing numeric/known-event formatting path remains covered by the helper test module.
- Ran
uv run --no-project --with pytest pytest tools/tests/test_webhook_client_helpers.py -q-> 6 passed. - Ran
python3 -m py_compile tools/webhooks/webhook_client.py tools/tests/test_webhook_client_helpers.py-> passed. - Ran
git diff --check origin/main...HEAD -- tools/webhooks/webhook_client.py tools/tests/test_webhook_client_helpers.py-> passed. - Manual probe of
format_event("large_tx", {"delta": "not-a-number", ...})produced the intendedDelta: ? RTC (out)line.
Duplicate/competition check immediately before this review: no submitted reviews on PR #6089 and no open rustchain-bounties claim matching 6089.
jaxint
left a comment
There was a problem hiding this comment.
LGTM! Great work on this PR. 🚀
BossChaos
left a comment
There was a problem hiding this comment.
Bounty: Bounty #73 | Security review
Wallet: RTC6d1f27d28961279f1034d9561c2403697eb55602
GitHub: BossChaos
Overview
PR #6089 adds error handling to the webhook client's format_event() function when formatting transaction delta values. The fix wraps the float() conversion in a try/except block, gracefully displaying ? when the delta value is non-numeric (e.g., a string, None, or dict) instead of crashing with a ValueError or TypeError.
Verdict: MEDIUM
Findings
1. [MEDIUM] Non-Numeric Delta Values Crash Webhook Notification Pipeline
File: tools/webhooks/webhook_client.py:75-80
Code (BEFORE):
lines.append(f" Delta: {data.get('delta', 0):+.6f} RTC ({data.get('direction', '?')})")Risk Description:
The format specifier :+.6f requires a numeric value. If the delta field in a large_tx event is a string (e.g., "not-a-number"), None, or any non-numeric type:
- Python raises
ValueError: Unknown format code 'f' for object of type 'str'. - This exception propagates up through the webhook formatting pipeline.
- The entire webhook notification fails to send — the operator receives no alert about the large transaction.
Attack scenario:
An attacker who can influence the delta field in transaction data (e.g., through a crafted transaction or manipulated API response) could cause:
- Silent failure of large transaction alerts.
- Operators missing critical balance change notifications.
- The attacker could drain funds without triggering alerts.
The fix (CORRECT):
try:
delta = f"{float(data.get('delta', 0)):+.6f}"
except (TypeError, ValueError):
delta = "?"Recommendation:
✅ Fix is correct. Additionally, consider logging when a malformed delta is encountered so operators can investigate:
except (TypeError, ValueError) as e:
delta = "?"
logging.warning(f"Malformed delta in large_tx event: {data.get('delta')!r} — {e}")2. [LOW] direction Field Also Unvalidated
The data.get('direction', '?') field is used directly in the formatted output. If direction is a complex object (dict, list), it would be stringified in the output (e.g., {'attack': True}), potentially exposing internal data in notification text.
Recommendation:
direction = data.get('direction', '?')
if not isinstance(direction, str):
direction = '?'3. [LOW] previous_balance and new_balance Also Unvalidated
Same issue applies to balance fields:
lines.append(f" Balance: {data.get('previous_balance', '?')} -> {data.get('new_balance', '?')} RTC")These use string interpolation so won't crash, but non-numeric values would produce confusing output like Balance: None -> {'malicious': True} RTC.
Summary
| Severity | Count | RTC |
|---|---|---|
| MEDIUM | 1 | 10 |
| LOW | 2 | 10 |
Total: 20 RTC
508704820
left a comment
There was a problem hiding this comment.
Security review: verify input validation, error handling, fail-closed defaults, no info leakage. - Xeophon
Summary
str | Noneannotations are otherwise evaluated at import timelarge_tx.deltavalues while formatting webhook console outputVerification
python3 -m py_compile tools/webhooks/webhook_client.py tools/tests/test_webhook_client_helpers.pyformat_event("large_tx", ...)checks for malformed and numeric delta valuesNote:
python3 -m pytest tools/tests/test_webhook_client_helpers.py -qcould not run in this local environment because the Xcode Python does not have pytest installed.