fix: harden security scan findings - #2
Conversation
Phase 9: close signed-cookie, RLS, abuse-control, CSV, scan, image, Sentry, and CI findings; add a service-role-only cost snapshot policy.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0a87b2dd9f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| buildWindows: (ip: string, now: number) => RateLimitReservation[] | ||
| ): Promise<AnonGuardResult> { | ||
| const ip = await clientIp(); | ||
| if (!(await verifyTurnstile(turnstileToken, ip))) { |
There was a problem hiding this comment.
Preserve the pre-Turnstile per-IP throttle
When TURNSTILE_SECRET_KEY is configured, a request with a missing or invalid token returns here before addToWindows, so the per-(ip, store) caps built by the order/subscribe callers never apply to failed challenges. A scripted flood can therefore force unbounded Cloudflare siteverify fetches without hitting KV, which removes the local abuse cap this guard is meant to provide; split a cheap per-IP/IP-store limit before Turnstile or otherwise throttle failed challenges without consuming the store-wide bucket.
Useful? React with 👍 / 👎.
| meta.width > MAX_EDGE || | ||
| meta.height > MAX_EDGE |
There was a problem hiding this comment.
Preserve downscaling for valid large uploads
For any JPG/PNG under 4 MB whose source dimensions exceed 2048 px on an edge, this new check rejects before the existing resize({ fit: "inside" }) can downscale it. The upload path still only pre-validates MIME and byte size, and the processor was designed to clamp dimensions, so common phone photos that used to be accepted will now fail with the misleading “under 4 MB” error; keep a separate input-pixel bomb cap while still allowing ordinary oversized photos to be normalized.
Useful? React with 👍 / 👎.
Summary
Closes the security-scan findings across admin session isolation, direct Supabase writes, abuse controls, CSV exports, scan attribution, image processing, Sentry diagnostics, and CI credential gating.
Adds a service-role-only RLS policy for
public.cost_snapshotin a forward migration.Verification
npm run verifynpm run test:integration(102/102)npm run audit:ciDeployment note
Apply
20260709212011_cost_snapshot_service_role_policy.sqlin Supabase before treating the new advisor finding as resolved in the linked database.