# Infinite HTTP client timeout in FeeService can freeze the sequencer

FeeService's reqwest client has no timeout, so a stalled mempool.space request blocks DA queueing, L1 block detection, and sequencer startup 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.5
- Library page: https://bugbountylibrary.com/r/cantina%3Acitrea_jul2025%3A3.2.5
- Tags: domain:infra domain:web3 impact:dos kind:contest platform:cantina sev:medium tech:rust technique:source-review vuln:dos

**Target:** Sequencer FeeService HTTP client (fee.rs)
**Root cause:** reqwest::get() builds a default Client with timeout and read_timeout both None, so no timer futures are created and a stalled connection waits forever.
**Steps:**
1. Read fee.rs#L204: get_fee_rate_from_mempool_space() uses reqwest::get()
2. Confirm reqwest v0.12.12 ClientBuilder defaults timeout/read_timeout to None
3. Run sequencer, then `sudo iptables -A OUTPUT -d mempool.space -j DROP`
4. Trigger any action calling get_fee_rate()
5. Observe DA transactions and L1 block detection halt; restart also hangs at get_da_block_data() in run()
**How found:** Code review of FeeService's fee fetch path, tracing reqwest::get() into ClientBuilder defaults and the PendingRequest future to confirm no timeout timers are polled when both are None.
**Exploitation:** Attacker with network control (ISP, cloud provider) blackholes or BGP-hijacks traffic to mempool.space; the awaited fee fetch never returns, blocking the DA transaction loop and L1BlockMonitor until manual restart.
**Escalation:** Chained into full sequencer halt: DA commitments stop, L1/DA block detection ceases, and startup hangs, requiring manual intervention.
**Insight:** When auditing Rust services, trace convenience helpers like reqwest::get() to their builder defaults—absence of timeout/read_timeout means no timer future is polled, so any awaited external call in a critical loop becomes an unbounded liveness risk.
