Skip to content

fix: tolerate malformed large tx deltas#6089

Open
jasperdevs wants to merge 1 commit into
Scottcjn:mainfrom
jasperdevs:jasper/webhook-large-tx-delta-202605211555
Open

fix: tolerate malformed large tx deltas#6089
jasperdevs wants to merge 1 commit into
Scottcjn:mainfrom
jasperdevs:jasper/webhook-large-tx-delta-202605211555

Conversation

@jasperdevs
Copy link
Copy Markdown
Contributor

Summary

  • make the webhook client importable on Python versions where str | None annotations are otherwise evaluated at import time
  • tolerate malformed large_tx.delta values while formatting webhook console output
  • add regression coverage for a non-numeric large transaction delta

Verification

  • python3 -m py_compile tools/webhooks/webhook_client.py tools/tests/test_webhook_client_helpers.py
  • direct format_event("large_tx", ...) checks for malformed and numeric delta values

Note: python3 -m pytest tools/tests/test_webhook_client_helpers.py -q could not run in this local environment because the Xcode Python does not have pytest installed.

@github-actions github-actions Bot added the BCOS-L1 Beacon Certified Open Source tier BCOS-L1 (required for non-doc PRs) label May 21, 2026
@github-actions
Copy link
Copy Markdown
Contributor

Welcome to RustChain! Thanks for your first pull request.

Before we review, please make sure:

  • Non-doc PRs have a BCOS-L1 or BCOS-L2 label
  • Doc-only PRs are exempt from BCOS tier labels when they only touch docs/**, *.md, or common image/PDF files
  • New code files include an SPDX license header
  • You've tested your changes against the live node

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!

Copy link
Copy Markdown

@bitdamii bitdamii left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved after focused local validation.

What I checked:

  • Confirmed the large_tx formatter no longer crashes when delta is non-numeric and now renders the safe ? RTC fallback.
  • 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 intended Delta: ? RTC (out) line.

Duplicate/competition check immediately before this review: no submitted reviews on PR #6089 and no open rustchain-bounties claim matching 6089.

Copy link
Copy Markdown
Contributor

@jaxint jaxint left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Great work on this PR. 🚀

Copy link
Copy Markdown
Contributor

@BossChaos BossChaos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

  1. Python raises ValueError: Unknown format code 'f' for object of type 'str'.
  2. This exception propagates up through the webhook formatting pipeline.
  3. 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

Copy link
Copy Markdown
Contributor

@508704820 508704820 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security review: verify input validation, error handling, fail-closed defaults, no info leakage. - Xeophon

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

BCOS-L1 Beacon Certified Open Source tier BCOS-L1 (required for non-doc PRs) size/S PR: 11-50 lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants