From 12fdc6391c6c0438199c2551d1586fe61ce973a6 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Tue, 21 Apr 2026 20:31:03 -0700 Subject: [PATCH] refactor(security): loosen /connect rate limit from 3/min to 300/min MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Setup keys are 24 random bytes (unbruteforceable), so a tight rate limit does not meaningfully prevent key guessing. It exists only to cap bandwidth, CPU, and log-flood damage from someone who discovered the ngrok URL. A legitimate pair-agent session hits /connect once; 300/min is 60x that pattern and never hit accidentally. 3/min caused pairing to fail on any retry flow (network blip, second paired client) with no upside. Per-IP tracking was considered and rejected — adds a bounded Map + LRU for defense already adequate at the global layer. Co-Authored-By: Claude Opus 4.7 (1M context) --- browse/src/token-registry.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/browse/src/token-registry.ts b/browse/src/token-registry.ts index 455391eb..09e45c82 100644 --- a/browse/src/token-registry.ts +++ b/browse/src/token-registry.ts @@ -473,10 +473,18 @@ export function restoreRegistry(state: TokenRegistryState): void { } } -// ─── Connect endpoint rate limiter (brute-force protection) ───── +// ─── Connect endpoint rate limiter (flood protection) ───── +// +// Global-only cap. Setup keys are 24 random bytes (unbruteforceable), so +// rate limiting here is not about preventing key guessing. It caps +// bandwidth, CPU, and log-flood damage from someone who discovered the +// ngrok URL. A legitimate pair-agent session hits /connect once, so +// 300/min is 60x that pattern and never hit accidentally. Per-IP tracking +// was considered and rejected: adds a bounded Map + LRU for defense +// already adequate at the global layer. let connectAttempts: { ts: number }[] = []; -const CONNECT_RATE_LIMIT = 3; // attempts per minute +const CONNECT_RATE_LIMIT = 300; // attempts per minute (~5/sec average) const CONNECT_WINDOW_MS = 60000; export function checkConnectRateLimit(): boolean { @@ -486,3 +494,8 @@ export function checkConnectRateLimit(): boolean { connectAttempts.push({ ts: now }); return true; } + +// Test-only reset. +export function __resetConnectRateLimit(): void { + connectAttempts = []; +}