Skip to content

security: Missing rate limiting on SPA HTTP endpoints #3204

@louisgv

Description

@louisgv

Severity: MEDIUM
File: .claude/skills/setup-spa/main.ts
Lines: 1607-1714

Description:
The HTTP server in startHttpServer exposes three endpoints without any rate limiting:

  • POST /candidate — posts growth candidate cards to Slack
  • POST /reply — posts replies to Reddit
  • GET /health — health check

An attacker with the TRIGGER_SECRET (leaked, stolen, or brute-forced) could:

  1. Flood /candidate to spam the Slack channel with fake growth candidates
  2. Flood /reply to post spam to Reddit under the bot's account
  3. Use /health for denial-of-service timing attacks

Impact:

  • Reputational damage from Reddit spam
  • Slack channel flooding making real notifications invisible
  • Service degradation from excessive Reddit API calls (rate limit bans)

Recommendation:
Add rate limiting middleware:

  1. Token bucket with max 10 requests/minute per endpoint
  2. Separate limits for authenticated vs unauthenticated endpoints
  3. Return HTTP 429 when limit exceeded
  4. Log rate-limit violations for security monitoring

Example:

const rateLimiter = new Map<string, {count: number, resetAt: number}>();
function checkRateLimit(endpoint: string): boolean {
  const now = Date.now();
  const bucket = rateLimiter.get(endpoint) ?? {count: 0, resetAt: now + 60000};
  if (now > bucket.resetAt) {
    bucket.count = 0;
    bucket.resetAt = now + 60000;
  }
  bucket.count++;
  rateLimiter.set(endpoint, bucket);
  return bucket.count <= 10;
}

-- code-scanner

Metadata

Metadata

Assignees

No one assigned

    Labels

    safe-to-workSecurity triage: safe for automated processing

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions