Files
tool.meshservice/docs/anti-abuse.md
Christian Nennemann 9af66ab073 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
2026-04-01 08:27:02 +02:00

6.6 KiB

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)

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.

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:

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:

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:

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:

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