Problem
The backend API lacks rate limiting on authentication and mutation endpoints, making it vulnerable to:
- Brute force attacks on OAuth flows
- Replay attacks on idempotent mutations
- DoS attacks exhausting database/Soroban RPC resources
Vulnerable Endpoints
Based on the API overview (README.md), these endpoints lack rate limiting:
Authentication
POST /api/auth/login - OAuth initiation
POST /api/auth/callback - OAuth completion
High-value mutations
POST /api/bounties/:id/fund
POST /api/bounties/:id/claim
POST /api/escrow/:id/release
POST /api/escrow/:id/refund
POST /api/milestones/:id/fund
POST /api/maintenance-pools/:id/deposit
POST /api/github/webhooks (external endpoint)
List endpoints (resource exhaustion)
GET /api/bounties
GET /api/milestones
GET /api/analytics/*
Attack Scenarios
1. Brute Force OAuth State Parameter
An attacker could repeatedly hit the OAuth callback trying different state values to hijack sessions.
2. Idempotency Key Exhaustion
The idempotency system has a 30-second conflict window. An attacker could:
- Generate thousands of UUIDs
- Send concurrent requests with unique keys
- Exhaust database connections and Soroban RPC quota
- Cause legitimate requests to fail
3. Webhook DoS
Without rate limiting, an attacker could flood /api/github/webhooks with invalid payloads to:
- Exhaust database with
WebhookEvent rows
- CPU spike from HMAC verification
- Block legitimate GitHub webhook deliveries
Recommended Solution
Implement multi-tier rate limiting with @nestjs/throttler:
// app.module.ts
import { ThrottlerModule, ThrottlerGuard } from '@nestjs/throttler';
@Module({
imports: [
ThrottlerModule.forRoot([
{
name: 'short',
ttl: 1000, // 1 second
limit: 3, // 3 requests
},
{
name: 'medium',
ttl: 60000, // 1 minute
limit: 20,
},
{
name: 'long',
ttl: 3600000, // 1 hour
limit: 100,
},
]),
],
providers: [
{
provide: APP_GUARD,
useClass: ThrottlerGuard,
},
],
})
export class AppModule {}
Per-endpoint overrides:
// Critical mutations: stricter limits
@Throttle({ short: { limit: 1, ttl: 1000 } })
@Post('bounties/:id/fund')
async fundBounty() { ... }
// Webhooks: separate limit by IP
@Throttle({ medium: { limit: 50, ttl: 60000 } })
@Post('github/webhooks')
async handleWebhook() { ... }
// Public lists: lenient but protected
@Throttle({ long: { limit: 1000, ttl: 3600000 } })
@Get('bounties')
async listBounties() { ... }
Redis-backed storage (production):
ThrottlerModule.forRoot({
storage: new ThrottlerStorageRedisService(new Redis({
host: process.env.REDIS_HOST,
port: parseInt(process.env.REDIS_PORT),
})),
})
Additional Hardening
- IP-based blocking: Ban IPs after N failed signature verifications
- Exponential backoff: Increase delays after repeated 429 responses
- Webhook IP allowlist: GitHub publishes their webhook source IPs - validate against them
- Per-user limits: Track limits by
userId for authenticated endpoints, not just IP
References
Priority
🟠 High - Should be implemented before public beta
Problem
The backend API lacks rate limiting on authentication and mutation endpoints, making it vulnerable to:
Vulnerable Endpoints
Based on the API overview (README.md), these endpoints lack rate limiting:
Authentication
POST /api/auth/login- OAuth initiationPOST /api/auth/callback- OAuth completionHigh-value mutations
POST /api/bounties/:id/fundPOST /api/bounties/:id/claimPOST /api/escrow/:id/releasePOST /api/escrow/:id/refundPOST /api/milestones/:id/fundPOST /api/maintenance-pools/:id/depositPOST /api/github/webhooks(external endpoint)List endpoints (resource exhaustion)
GET /api/bountiesGET /api/milestonesGET /api/analytics/*Attack Scenarios
1. Brute Force OAuth State Parameter
An attacker could repeatedly hit the OAuth callback trying different state values to hijack sessions.
2. Idempotency Key Exhaustion
The idempotency system has a 30-second conflict window. An attacker could:
3. Webhook DoS
Without rate limiting, an attacker could flood
/api/github/webhookswith invalid payloads to:WebhookEventrowsRecommended Solution
Implement multi-tier rate limiting with
@nestjs/throttler:Per-endpoint overrides:
Redis-backed storage (production):
Additional Hardening
userIdfor authenticated endpoints, not just IPReferences
Priority
🟠 High - Should be implemented before public beta