fix: harden bridge confirmation thresholds#6524
Conversation
eliasx45
left a comment
There was a problem hiding this comment.
Thanks for tightening this path. I like the direction of moving threshold checks into update_external_confirmation() because it protects direct helper callers, not just Flask requests, and the new helper-level regression for bypassing route parsing passes locally.
I found one blocker before this is ready, though: the HTTP callback route still clamps over-ceiling values before calling the hardened helper, so over-ceiling route input is not actually rejected. In register_bridge_routes(), both confirmations and required_confirmations are parsed with _parse_non_negative_int_arg(..., max_value=1000), and that parser uses min(parsed, max_value). That means a callback body with confirmations = BRIDGE_MAX_CONFIRMATIONS + 1 is normalized to 1000; the helper never sees the over-ceiling input and can complete the transfer.
Local reproduction on current head c5b23975b6ffa71527c976720c66ae8a74418c2e:
- Created a deposit bridge transfer using the existing
tests/test_bridge_lock_ledger.pyfixture schema. - Posted to
/api/bridge/update-externalwith validX-API-Key, the transfertx_hash,external_tx_hash, andconfirmations = bridge_api.BRIDGE_MAX_CONFIRMATIONS + 1. - Actual result: HTTP 200 with
{'external_confirmations': 1000, 'ok': True, 'required_confirmations': 12, 'status': 'completed', ...}. - Stored transfer result:
status = completed,external_confirmations = 1000.
I expected the route to return 400 and leave the transfer pending, matching the new helper-level rejection. A route-level regression for oversized confirmations and oversized required_confirmations would catch this; alternatively the route parser could reject rather than clamp for this endpoint, or call the helper with the raw parsed integer so the new core guard remains authoritative.
Other validation performed:
C:\Users\home\Downloads\0-Elias\coprinter\Rustchain\.venv\Scripts\python.exe -m pytest -q tests/test_bridge_lock_ledger.py::TestIntegration::test_full_deposit_flow tests/test_bridge_lock_ledger.py::TestIntegration::test_external_confirmation_rejects_lowered_required_threshold tests/test_bridge_lock_ledger.py::TestIntegration::test_external_confirmation_helper_rejects_unbounded_counts-> 3 passed.C:\Users\home\Downloads\0-Elias\coprinter\Rustchain\.venv\Scripts\python.exe -m py_compile node/bridge_api.py tests/test_bridge_lock_ledger.py-> passed.git diff --check origin/main...HEAD-> clean.gh pr checks 6524 -R Scottcjn/Rustchain->testis failing; other listed checks pass.
Requesting changes so the public callback path enforces the same over-ceiling rejection as the helper path.
|
Merged + paid 25 RTC (Bug Bounty Medium #2867). tx: Bridge confirmation hardening is timely — coincides with federation RFC #6522 and upstream proposal. Bridge custody primitives in Thanks @sirakinb. |
Summary
Fixes #6521 by moving bridge confirmation threshold enforcement into
update_external_confirmation()instead of relying only on the HTTP parser.Changes
BRIDGE_MAX_CONFIRMATIONSceiling.required_confirmationsthreshold.Verification
./.venv/bin/python -m pytest -q tests/test_bridge_lock_ledger.py::TestIntegration::test_full_deposit_flow tests/test_bridge_lock_ledger.py::TestIntegration::test_external_confirmation_rejects_lowered_required_threshold tests/test_bridge_lock_ledger.py::TestIntegration::test_external_confirmation_helper_rejects_unbounded_counts-> 3 passedPYTHONPYCACHEPREFIX=/private/tmp/rustchain-pycache python3 -m py_compile node/bridge_api.py tests/test_bridge_lock_ledger.pygit diff --checkNote: the full
tests/test_bridge_lock_ledger.pysuite currently has unrelated failures on currentmainaround existing address/auth expectations; the targeted bridge confirmation regressions pass.