Document hashcash proof-of-work plan for session rate limiting
This commit is contained in:
parent
368ef4dfc9
commit
097c24f498
43
README.md
43
README.md
@ -648,6 +648,49 @@ Per gohttpserver conventions:
|
||||
11. **Signable messages** — optional Ed25519 signatures with TOFU key
|
||||
distribution. Servers relay signatures without verification.
|
||||
|
||||
### Rate Limiting & Abuse Prevention
|
||||
|
||||
Session creation (`POST /api/v1/session`) will require a
|
||||
[hashcash](https://en.wikipedia.org/wiki/Hashcash)-style proof-of-work token.
|
||||
This is the primary defense against resource exhaustion — no CAPTCHAs, no
|
||||
account registration, no IP-based rate limits that punish shared networks.
|
||||
|
||||
**How it works:**
|
||||
|
||||
1. Client requests a challenge: `GET /api/v1/challenge`
|
||||
2. Server returns a nonce and a required difficulty (number of leading zero
|
||||
bits in the SHA-256 hash)
|
||||
3. Client finds a counter value such that `SHA-256(nonce || counter)` has the
|
||||
required leading zeros
|
||||
4. Client submits the proof with the session request:
|
||||
`POST /api/v1/session` with `{"nick": "...", "proof": {"nonce": "...", "counter": N}}`
|
||||
5. Server verifies the proof before creating the session
|
||||
|
||||
**Adaptive difficulty:**
|
||||
|
||||
The required difficulty scales with server load. Under normal conditions, the
|
||||
cost is negligible (a few milliseconds of CPU). As concurrent sessions or
|
||||
session creation rate increases, difficulty rises — making bulk session creation
|
||||
exponentially more expensive for attackers while remaining cheap for legitimate
|
||||
single-user connections.
|
||||
|
||||
| Server Load | Difficulty | Approx. Client CPU |
|
||||
|--------------------|------------|--------------------|
|
||||
| Normal (< 100/min) | 16 bits | ~1ms |
|
||||
| Elevated | 20 bits | ~15ms |
|
||||
| High | 24 bits | ~250ms |
|
||||
| Under attack | 28+ bits | ~4s+ |
|
||||
|
||||
**Why hashcash and not rate limits?**
|
||||
|
||||
- No state to track (no IP tables, no token buckets)
|
||||
- Works through NATs and proxies — doesn't punish shared IPs
|
||||
- Cost falls on the requester, not the server
|
||||
- Fits the "no accounts" philosophy — proof-of-work is the cost of entry
|
||||
- Trivial for legitimate clients, expensive at scale for attackers
|
||||
|
||||
**Status:** Not yet implemented. Tracked for post-MVP.
|
||||
|
||||
## Status
|
||||
|
||||
**Implementation in progress.** Core API is functional with SQLite storage and
|
||||
|
||||
Loading…
Reference in New Issue
Block a user