# Infinite timeout in the Bitcoin JSON-RPC client can freeze all critical Citrea compoments

Citrea's forked Bitcoin JSON-RPC client uses reqwest with no timeouts, so a stalled connection hangs sequencer, full node, prover and light client indefinitely.

- Payout: Contest reward
- Severity: medium
- Program: Citrea
- Credited: marchev
- Disclosed: 2025-10-21
- Write-up quality: 6/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_citrea_jul2025.pdf#3.2.2
- Library page: https://bugbountylibrary.com/r/cantina%3Acitrea_jul2025%3A3.2.2
- Tags: domain:web3 impact:dos kind:contest platform:cantina sev:medium tech:rust technique:regression technique:source-review vuln:dos

**Target:** Bitcoin Core JSON-RPC client (reqwest transport) in DA service
**Root cause:** Chainway's fork of rust-bitcoincore-rpc replaced the simple_http transport (15s default timeout) with reqwest::Client::new(), which sets no read or total timeout, so stalled requests never error.
**Steps:**
1. Run the Citrea sequencer locally
2. Drop traffic to Bitcoin Core: `sudo iptables -A OUTPUT -d <bitcoin-node-ip> -j DROP`
3. Trigger or wait for any DA logic
4. Observe the RPC call hang indefinitely; exponential backoff never triggers since no error returns
**How found:** Code review comparing the upstream crate's simple_http transport (DEFAULT_TIMEOUT 15s) against Chainway's fork PR 5 swapping in reqwest::Client::new(); traced reqwest internals to confirm None timeouts skip all timeout logic, and noted backoff only fires on returned errors.
**Exploitation:** Not an attacker payload; any network stall (packet loss, blackhole, routing loop, BGP hijack) to the Bitcoin Core node causes awaited RPC calls in BitcoinService to block forever, freezing the component.
**Escalation:** Single shared DA client means one stalled connection affects sequencer, full node, batch prover and light client simultaneously — systemic liveness failure.
**Insight:** When auditing forks of well-known libraries, diff the transport/network layer against upstream defaults — swapping in a client like reqwest::Client::new() silently drops timeouts, and retry/backoff logic is useless against hangs that never return an error.
