Repository navigation
feat: add standalone Cap status app - #2475
Conversation
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
| return Response.json(publicSnapshot(await readState(getRedis())), { | ||
| headers: { | ||
| "Cache-Control": | ||
| "public, max-age=0, s-maxage=30, stale-while-revalidate=30", |
There was a problem hiding this comment.
P2: Unique query strings bypass the status API cache and repeatedly consume Redis and function resources.
Unique query strings bypass the 30-second per-URL cache; each miss reads the dedicated Redis store.
Reject query strings and apply an edge rate limit before the Redis-backed handler.
AI prompt
Check if this security scanner issue is valid. If so, understand the root cause and fix it. If appropriate, update or add tests. Keep the change focused and preserve intended behavior.
<file name="apps/status/app/api/status/route.ts">
<violation number="1" location="apps/status/app/api/status/route.ts:11">
<priority>P2</priority>
<title>Unique query strings bypass the status API cache and repeatedly consume Redis and function resources.</title>
<evidence>The new public GET handler reads the dedicated Redis state at line 8, then sets `Cache-Control: public, max-age=0, s-maxage=30, stale-while-revalidate=30` at line 11. The handler does not inspect or reject query parameters, so an unauthenticated caller can request `/api/status?x=<unique-value>` for each request. Vercel's official CDN documentation says function responses are cached when they set `s-maxage` (https://vercel.com/docs/caching/cdn-cache), and its cache-key documentation says the request URL is part of the cache key, with query strings ignored only for static files (https://vercel.com/docs/caching/cdn-cache/purge). These distinct function URLs therefore create distinct cache entries rather than reusing the intended 30-second cache. Each cache miss runs `readState(getRedis())` and performs a Redis GET; `publicSnapshot` then projects six services across 90 history days (`apps/status/lib/state.ts:152-175`). The app provides no query normalization/rejection or per-caller rate limit before the Redis read. The package pins Next.js 16.3.0 (`apps/status/package.json:15`); Vercel documents the function-response caching behavior used here. Repeated unique requests can consume the status deployment's function invocations and dedicated Redis request quota, affecting availability and/or exhausting usage limits.</evidence>
<recommendation>Reject requests with any query string before calling `getRedis()` and enforce an edge-level rate limit or request quota for `/api/status`. Keep the public cache on a single canonical URL so caller-controlled URL variants cannot force repeated Redis reads.</recommendation>
</violation>
</file>
There was a problem hiding this comment.
Fixed the cache-busting path in 6807174: requests with query parameters return 400 before getRedis() or readState(). The regression test covers multiple unique and encoded query strings and asserts zero Redis commands. The production HTTP check confirms the same behavior. The separate status project’s WAF rate-limit setup is documented as a requirement before public launch; no production firewall configuration has been changed by this PR.
There was a problem hiding this comment.
The developer’s fix directly remediates the reported cache bypass by rejecting requests with query parameters before any Redis interaction, and the regression tests verify that no Redis commands are issued for cache-busting URLs. Treating edge rate limiting as an infrastructure/WAF prerequisite documented for public launch is a reasonable separation of concerns, so this reply satisfactorily addresses the finding.
|
@greptileai please rereview |
Adds a standalone status app for
status.cap.so, matching the current Cap landing page’s typography, clouds, colours, and spacing. It can be deployed to its own Vercel project without importing the main web app or using its database.Behaviour
Deployment
Create a separate Vercel project with root
apps/statuson a plan supporting five-minute cron jobs. Attach a dedicated Upstash database and configureCRON_SECRETplus the service URLs listed in the app README. Website and authentication defaults are supplied; sharing/storage canaries and media/render health URLs require configuration. Add an external heartbeat monitor to detect scheduler or Vercel-wide failures, and configure the documented Vercel WAF rate limit before public launch.This PR does not deploy production infrastructure or change DNS. These are availability probes, not complete recording/upload/playback transactions.
Validation
Screenshots
Production-build previews with clearly labelled sample data; these do not represent live uptime.
Desktop · Mobile

Confidence Score: 5/5
The PR appears safe to merge; the previous finding is fixed and no new blocking issues were found.Summary
Adds a standalone Cap status app with scheduled checks, Redis history, and a public status page.
Reviews (2) · Last reviewed commit: "fix: isolate status development and prot..." · Reviewed by Greptile