Skip to content

[SECURITY][MEDIUM] In-memory rate limit bypass across Vercel instances #2341

Description

@axeleagle1

Summary

When Upstash Redis is unconfigured (or falls back to in-memory), the rate limiter becomes per-Vercel-instance. On Vercel's Edge Network, each request may hit a different serverless instance, resetting the counter. An attacker distributing requests across cold starts can bypass rate limits entirely.

Affected Component

middleware.ts - Rate limiting logic

Vulnerability Details

The code has two rate limiting paths:

  1. Upstash Redis (distributed) - Globally consistent across instances
  2. In-memory fallback (per-instance) - Only tracks requests within a single isolate

When Redis is unavailable, the middleware falls back to an in-memory Map. On Vercel:

  • Each cold start creates a fresh Map
  • An attacker can send 120 requests to instance A (hits limit), then send 120 to instance B (fresh Map, no limit), etc.
  • The console.warn in the code acknowledges this: "NOTE: This is per-isolate only"
// NOTE: This is per-isolate only — it does NOT share state across Vercel Edge
// instances.  For reliable distributed enforcement, configure Upstash Redis

Impact

Medium - An attacker can bypass rate limits on any API endpoint, enabling:

  • DoS via resource exhaustion
  • Brute-force attacks on protected endpoints
  • Abuse of the RPC proxy to drain paid Helius quota

Proof of Concept

# Send 120 requests (hits limit on single instance)
for i in $(seq 1 120); do curl -s https://percolatorlaunch.com/api/rpc; done

# Wait for cold start, repeat - counter resets
sleep 30
for i in $(seq 1 120); do curl -s https://percolatorlaunch.com/api/rpc; done

Recommended Fix

  1. Primary: Ensure Upstash Redis is configured in production (check deployment docs)
  2. Defense-in-depth: Add a fallback rate limiter using Supabase (already available)
  3. Monitoring: Alert when in-memory fallback is active in production

Environment

  • Production: percolatorlaunch.com
  • Affected when UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN are not set

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions