Fix 25 confirmed bugs from code audit#445
Open
simon-lowes wants to merge 3 commits into
Open
Conversation
Addresses all confirmed audit findings: Correctness / logic - interlink-utils: parse YYYY-MM-DD lag keys as LOCAL dates (no UTC off-by-one) - date-utils: add parseLocalDateString; use it in chart/tooltip formatters - configGenerationService: drop bare length<=3 generic heuristic and guard against malformed location/trigger items (no TypeError on missing label) - syncService: derive backoff from real prior-attempt count, mark syncing after the backoff wait so the counter is not one cycle behind - App: load trackers once per session (drop currentView dep) with a one-shot welcome-redirect ref, preventing optimistic-add clobber and redundant reads - TrackerSelector: store null (not literal 'other') for confirmed_interpretation - DateRangePicker: compare against startOfDay(minDate) so earliest entry's day remains selectable - use-theme-onboarding: detect 'system' from baseline-theme-mode key; increment CTA show-count only when the CTA is actually shown Security - analytics-utils + csv-export: route exports through hardened escapeCSV (quote/escape all fields, formula-injection guard); escape v2 headers; preserve custom-field data in multi-tracker export via per-tracker sections - prompt-sanitizer: make injection patterns global so every occurrence is neutralized; also neutralize external API content (second-order injection) - distributed-rate-limiter: fail CLOSED by default on backend errors (configurable failOpen) to keep quota enforcement on paid AI endpoints - migration: add WITH CHECK to tracker_entries/profiles UPDATE RLS policies - supabaseAuth: only sign out on definitive 401/403 auth errors, keep session on transient network/server failures - useAuth: enforce documented no-remember sign-out on browser-close - useFormDraft: add enabled flag; PainEntryForm disables draft persistence when editing so it cannot clobber the new-entry draft - stateEncoder: validate decoded view against the known union and trackerId type Test hardening - edge-function-security.test: verify a real status:401 Response co-located with the auth check; scan whole file for any .text() variable leaked via throw, JSON.stringify, or Response body - prompt-sanitizer.test: add repeated-phrase and external second-order cases - xss-safety.test: use negative lookbehind so line-leading eval( is detected Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The audit flagged the UPDATE RLS policies on tracker_entries/profiles as lacking WITH CHECK based on the migration files. Verifying against the live database (pg_policies + security advisors) shows the policies already carry WITH CHECK ((select auth.uid()) = user_id/id) — they were tightened and renamed via the Supabase dashboard, so the change never landed in a migration file. This migration referenced the old policy names and would have created a duplicate UPDATE policy in production rather than fixing anything. Removing it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Three migrations were applied to the production database to close issues the code-only audit could not see (Supabase security advisors), now recorded as migration files (version IDs match the remote migration history, so they are recognised as already-applied and are rebuild-guarded): - restrict_maintenance_function_execution: ~19 SECURITY DEFINER admin/maintenance functions (cleanup_security_events, cleanup_audit_logs, run_database_maintenance, fix_rls_policies, ...) were EXECUTE-able by anon/authenticated via PostgREST RPC. Revoked from public/anon/authenticated; service_role retained. - restrict_tracker_images_listing: dropped the broad authenticated SELECT policy on the public tracker-images bucket that allowed cross-user file enumeration. - restrict_set_ambiguous_terms_trigger_fn: revoked direct EXECUTE on a trigger fn. Note: the repo migrations remain out of sync with production (much of the live schema was applied via the Supabase dashboard). A full re-baseline should be done with `supabase db pull`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Automated audit fixes (25 findings)
Fixes for confirmed bugs found in an automated code audit. Every change was verified and independently reviewed (verdict: pass).
Fixed
Decisions / assumptions
Verification
npm ci installed deps cleanly (0 vulnerabilities). tsc --noEmit on the src project produced 48 errors that are ALL pre-existing (identical count and set on a fresh main worktree; none reference any file I changed - they are lucide-react deep-import path issues and other base-branch issues, which is why the repo's build script uses tsc -b --noCheck). vitest: with the required VITE_SUPABASE_URL/VITE_SUPABASE_ANON_KEY env vars set, all 13 suites / 315 tests pass, including the prompt-sanitizer, edge-function-security, xss-safety, and configGenerationService suites I touched. Without env vars, 3 suites fail at import time on a missing-env guard in supabaseClient.ts (a harness config issue, not a code regression). eslint on all changed src files: 0 errors (only pre-existing warnings, none on lines I added). deno check passed on both edited edge-function shared files. The new SQL migration is standard idempotent Postgres RLS DDL matching existing migration style (no offline SQL tooling available, but syntax verified by inspection). Did not run e2e/Playwright/dev server per instructions.
Reviewer notes (non-blocking)
trigLabels.length <= 4 && every(...)tolength > 0 && every(...)), which the original finding only called out for locations. It is a correct improvement in the same direction and type-safe (config.triggers is string[]), but slightly beyond the stated finding.🤖 Generated with Claude Code