feat: add anti-abuse mechanisms

Prevent slot blocking and reservation spam:
- RateLimiter: per-sender cooldowns, hourly limits, pending caps
- ProofOfWork: Hashcash-style PoW for reservation requests
- SenderReputation: track honor rate, no-shows, auto-block
- TherapistPolicy: configurable requirements per provider
- 7 new tests (39 total)

Docs: docs/anti-abuse.md with implementation roadmap
This commit is contained in:
2026-04-01 08:27:02 +02:00
parent c757494cbe
commit 9af66ab073
445 changed files with 760 additions and 8 deletions

216
docs/anti-abuse.md Normal file
View File

@@ -0,0 +1,216 @@
# Anti-Abuse: Preventing Slot Blocking
## Problem
Bad actors could abuse the reservation system by:
1. **Slot Squatting**: Reserving slots with no intention to attend
2. **Denial of Service**: Mass-reserving to block legitimate patients
3. **Competitor Sabotage**: Blocking a therapist's calendar
4. **Spam Queries**: Flooding the network with fake queries
## Defense Layers
### Layer 1: Rate Limiting (Protocol Level)
```rust
pub struct RateLimits {
/// Max reservations per sender per hour
pub max_reservations_per_hour: u8, // Default: 3
/// Max pending (unconfirmed) reservations per sender
pub max_pending_reservations: u8, // Default: 2
/// Min time between reservations (seconds)
pub reservation_cooldown_secs: u32, // Default: 300 (5 min)
/// Max queries per sender per minute
pub max_queries_per_minute: u8, // Default: 10
}
```
**Implementation**: Each relay tracks sender activity and drops excessive requests.
### Layer 2: Reservation Deposits (Economic)
Require a small proof-of-work or micro-deposit to make reservations:
| Method | Cost to Attacker | UX Impact |
|--------|------------------|-----------|
| **Hashcash PoW** | CPU time (~1-5s per reservation) | Slight delay |
| **Token Stake** | Loses stake on no-show | Requires token system |
| **Reputation Bond** | Loses reputation on abuse | Requires history |
**Recommended**: Start with Hashcash PoW — no external dependencies.
```rust
pub struct ReservationProof {
/// Hashcash proof-of-work (20-bit difficulty)
pub pow_nonce: u64,
/// Hash must start with N zero bits
pub difficulty: u8,
}
impl ReservationProof {
pub fn verify(&self, reservation_id: &[u8; 16]) -> bool {
let hash = sha256([reservation_id, &self.pow_nonce.to_le_bytes()].concat());
leading_zeros(&hash) >= self.difficulty
}
}
```
### Layer 3: Confirmation Requirements
Therapists can require confirmation steps:
```rust
pub enum ConfirmationMode {
/// Auto-confirm (trust network)
AutoConfirm,
/// Require patient to solve CAPTCHA-like challenge
ChallengeResponse { challenge: Vec<u8> },
/// Require callback to verify contact
ContactVerification { method: ContactMethod },
/// Manual review by therapist
ManualReview,
}
```
### Layer 4: No-Show Tracking
Track reservation outcomes per sender:
```rust
pub struct SenderReputation {
pub address: [u8; 16],
pub reservations_made: u32,
pub reservations_honored: u32,
pub reservations_cancelled: u32, // With notice
pub no_shows: u32, // Without notice
pub last_no_show: Option<u64>,
}
impl SenderReputation {
pub fn honor_rate(&self) -> f32 {
if self.reservations_made == 0 { return 0.5; }
(self.reservations_honored as f32) / (self.reservations_made as f32)
}
pub fn is_blocked(&self) -> bool {
self.no_shows >= 3 || self.honor_rate() < 0.5
}
}
```
**Therapists can share blocklists** via signed messages:
```rust
pub struct BlocklistEntry {
pub blocked_address: [u8; 16],
pub reason: BlockReason,
pub reported_by: [u8; 16],
pub signature: [u8; 64],
pub timestamp: u64,
}
pub enum BlockReason {
NoShow,
Spam,
Harassment,
FakeIdentity,
}
```
### Layer 5: Reservation Limits per Therapist
Therapists set their own limits:
```rust
pub struct TherapistPolicy {
/// Max pending reservations from new senders
pub max_pending_new: u8, // Default: 1
/// Max pending from established senders
pub max_pending_established: u8, // Default: 3
/// Require verification level for reservations
pub min_verification_level: u8, // 0 = any, 2 = peer-endorsed
/// Auto-reject senders with low honor rate
pub min_honor_rate: f32, // Default: 0.7
}
```
## Implementation Roadmap
### Phase 1: Basic Rate Limiting (Week 1)
- [ ] Add `RateLimiter` to `ServiceRouter`
- [ ] Track per-sender reservation counts
- [ ] Drop excessive requests with `ServiceAction::RateLimited`
### Phase 2: Proof-of-Work (Week 2)
- [ ] Add `ReservationProof` to reserve message payload
- [ ] Verify PoW before processing reservation
- [ ] Adaptive difficulty based on network load
### Phase 3: Reputation System (Week 3-4)
- [ ] `SenderReputation` storage
- [ ] Honor/no-show reporting from therapists
- [ ] Blocklist propagation
### Phase 4: Therapist Policies (Week 4+)
- [ ] Policy field in `SlotAnnounce`
- [ ] Policy enforcement in reservation handling
## Example: Complete Anti-Abuse Flow
```
Patient Relay Therapist
| | |
|-- Query (CBT, 104xx) -->| |
|<-- Matches (3 slots) ---| |
| | |
|-- Reserve (slot_id) --->| |
| + PoW proof | |
| (1.2s computation) | |
| |-- Check rate limit ------>|
| | (OK: 1st today) |
| |-- Check reputation ------>|
| | (OK: new sender, 0.5) |
| |-- Forward reserve ------->|
| | |
| |<-- Confirm (pending) -----|
|<-- Pending -------------| |
| | |
| [Patient attends] | |
| |<-- Outcome: honored ------|
| | (reputation += 1) |
```
## Edge Cases
### New Users (No History)
- Allow 1 pending reservation
- Require PoW
- Lower priority than established users
### Therapist Gaming the System
- Therapists could falsely report no-shows
- Mitigation: Require mutual confirmation (patient confirms attendance too)
- Weight reports by reporter reputation
### Sybil Attacks (Many Fake Identities)
- Each identity requires new Ed25519 keypair
- PoW per reservation makes mass-blocking expensive
- Cross-relay blocklist sharing limits damage
## Privacy Considerations
- Reputation is tied to mesh address, not real identity
- No-show reports don't reveal appointment details
- Blocklists only contain addresses + reason, not personal data
## Metrics to Monitor
| Metric | Healthy Range | Alert Threshold |
|--------|---------------|-----------------|
| Reservation/Confirm ratio | > 0.8 | < 0.5 |
| Unique senders per relay | Growing | Flat with high volume |
| PoW rejection rate | < 5% | > 20% |
| Blocklist growth | Slow | Rapid spike |