Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
Commit4d4bd4b

fix(security): rate-limit /mcp and the v1 REST API

fix(security): rate-limit /mcp and the v1 REST API

apiRateLimit was only wired to /api/v2/*; the v1 /api/* routes
(src/routes/api.ts) and /mcp had no rate limiting at all. /mcp in
particular is the primary AI-agent interface, reachable anonymously
for read tools, and can trigger expensive per-call work -- e.g.
gluecron_repo_health runs the same per-file security-pattern scan
used by the repo health page, dozens of git subprocess spawns per
call. Nothing stopped that from being hammered.

Both new routes already run softAuth upstream, so the existing
authedMultiplier (4x cap for a signed-in/PAT'd caller vs anonymous)
applies automatically, same as every other rate-limited route.
ccantynz-alt committed on July 20, 2026Parent: 3b77289
1 file changed+1114d4bd4b8d05f56e991838e18b3549f3305055978
1 changed file+11−1
Modifiedsrc/app.tsx+11−1View fileUnifiedSplit
211211import incidentHookRoutes from "./routes/incident-hooks";
212212import workspaceRoutes from "./routes/ai-workspace";
213213import workspaceHubRoutes from "./routes/workspace-hub";
214import { authRateLimit, gitRateLimit, searchRateLimit } from "./middleware/rate-limit";
214import { apiRateLimit, authRateLimit, gitRateLimit, searchRateLimit } from "./middleware/rate-limit";
215215import { csrfToken, csrfProtect } from "./middleware/csrf";
216216import { noCache } from "./middleware/no-cache";
217217
390390app.use("/:owner/:repo/search", searchRateLimit);
391391app.use("/explore", searchRateLimit);
392392
393// Rate limit the v1 REST API and the MCP surface. api-v2 already applies its
394// own apiRateLimit internally (this stacks harmlessly for /api/v2/*); v1
395// (src/routes/api.ts) and /mcp had NO rate limiting at all despite /mcp
396// being the primary, anonymously-reachable AI-agent interface and able to
397// trigger expensive per-call work (e.g. gluecron_repo_health scans every
398// file in a repo). softAuth already runs on both, so the existing
399// authedMultiplier (4x for a signed-in caller) applies automatically.
400app.use("/api/*", apiRateLimit);
401app.use("/mcp", apiRateLimit);
402
393403// No-cache for HTML — ensures browsers and proxies never serve stale pages.
394404// The middleware only stamps text/html responses so static assets keep
395405// their own cache policies unchanged.
396406