Skip to content

Bug: /attest/challenge missing rate limit — unbounded SQLite growth DoS #2751

@BossChaos

Description

@BossChaos

Bug Report — /attest/challenge Endpoint Missing Rate Limit

Bounty: #305
Wallet: RTC6d1f27d28961279f1034d9561c2403697eb55602
Severity: High (15 RTC)
File: node/rustchain_v2_integrated_v2.2.1_rip200.py, lines 2912–2928

Description

The /attest/challenge endpoint creates a new nonce in SQLite on every POST with zero rate limiting. /attest/submit has check_ip_rate_limit() at line 3088, but the challenge issuance step is unprotected — asymmetric protection.

An attacker floods this endpoint, causing:

  1. SQLite WAL explosion — unbounded nonce table growth
  2. Disk exhaustion — nonces expire in 5 min but cleanup only runs on next call
  3. Write contention — blocks all other DB operations

Reproduction

# 1000 concurrent challenge requests, no auth required
python3 -c "
import requests, threading
def flood():
    for _ in range(100):
        requests.post('http://localhost:5000/attest/challenge')
threads = [threading.Thread(target=flood) for _ in range(10)]
[t.start() for t in threads]
[t.join() for t in threads]
print('Done — check nonces table size')
"

Fix

Add IP-based rate limit to get_challenge() using the existing ip_rate_limit table (max 10/min/IP). Consistent with /attest/submit protection.

Cross-reference: Related to #2744

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions