SECURITY REVIEW

SECURITY AUDIT REPORT

Full review of all security findings and remediations applied to TruckerFit. All findings from the audit are addressed or accepted with documented rationale.

10
Total Findings
9
Fixed
1
Accepted Risk
1
Critical
2
High
4
Medium
3
Low

SECURITY POSTURE BY AREA

Current hardening applied across each layer of the application.

Database & RLS
  • RLS enabled on all 6 tables
  • INSERT/SELECT/UPDATE/DELETE policies scoped to auth.uid()
  • No WITH CHECK (true) policies remain
  • CHECK constraints on all numeric and enum columns
  • photo_url restricted to https:// only
  • Text columns length-capped at the database layer
Frontend Code
  • HTML escaper (esc()) applied to all print window interpolations
  • maxLength enforced on all free-text inputs
  • Rating validated to 1–5 before insertion
  • Trimmed strings sliced to max length before Supabase calls
Browser & Network
  • Content-Security-Policy restricts scripts, styles, images, connections
  • X-Frame-Options: DENY prevents clickjacking
  • X-Content-Type-Options: nosniff blocks MIME sniffing
  • Referrer-Policy: strict-origin-when-cross-origin
  • Permissions-Policy limits geolocation/camera to self
  • Service worker only caches 200 OK same-origin responses

FINDINGS & REMEDIATIONS

Every finding from the audit with its root cause and applied fix.

CRITICAL FIXED
feedback table — RLS policy

RLS INSERT Policy Always True

VULNERABILITY

The original "Anyone can submit feedback" policy used WITH CHECK (true), allowing any caller to insert rows with any user_id — including impersonating another user's UUID.

REMEDIATION

Replaced with two scoped policies: anon users may only insert with user_id IS NULL; authenticated users may only claim their own auth.uid() or NULL.

HIGH FIXED
weight_logs, workout_logs, meal_logs, feedback, progress_photos

No Server-Side Input Constraints

VULNERABILITY

All numeric and text columns relied solely on browser-side HTML attributes (min/max/maxLength), which can be bypassed by direct Supabase API calls or DevTools manipulation.

REMEDIATION

Added database-level CHECK constraints: weight 50–1500 lbs, duration 0–1440 min, calories 0–10,000, protein 0–1,000 g, text columns capped at 200–5,000 chars, enum columns restricted to known valid values.

HIGH FIXED
progress_photos.photo_url column

javascript: URI Injection via photo_url

VULNERABILITY

The photo_url column accepted any text value. A direct API call could store a javascript: URI that executes when the URL is used in an <img> src or rendered as a link.

REMEDIATION

Added CHECK constraint: photo_url LIKE 'https://%'. Only HTTPS URLs are accepted at the database layer.

MEDIUM FIXED
MealPlans.tsx — handlePrint()

XSS via Unescaped Strings in Print Window

VULNERABILITY

The print function built an HTML string using template literals and wrote it to a new window via document.write(). If meal data ever contained <script> tags or HTML entities, they would execute in the print context.

REMEDIATION

Added an esc() helper that escapes &, <, >, ", and ' before every value is interpolated into the HTML string.

MEDIUM FIXED
index.html

No Content Security Policy

VULNERABILITY

No CSP was set, meaning any injected inline script or unexpected external resource could execute without restriction.

REMEDIATION

Added a strict CSP meta tag allowing scripts only from self + Google Tag Manager, styles from self + Google Fonts, images from self + Supabase Storage + Pexels, and connections only to self + Supabase. Added X-Frame-Options: DENY, X-Content-Type-Options: nosniff, Referrer-Policy, and Permissions-Policy.

MEDIUM FIXED
public/sw.js

Service Worker Caches Error Responses

VULNERABILITY

The original service worker cached any response where res.ok was true, including cross-origin requests and responses with Cache-Control: no-store. A poisoned or redirected response could be served indefinitely to offline users.

REMEDIATION

Added isCacheable() guard: only 200 OK same-origin basic responses without no-store are stored. Cross-origin requests (fonts, analytics) are explicitly excluded. Failed navigations fall back to cached / before returning a 503.

MEDIUM FIXED
FeedbackSection.tsx

Unbounded Text Input in Feedback Form

VULNERABILITY

The message textarea and name input had no maxLength attribute, allowing arbitrarily large payloads to be submitted from the browser.

REMEDIATION

Added maxLength={5000} on message and maxLength={200} on name. Submit handler also slices and validates before insertion. Character counter turns red near the limit.

LOW FIXED
workout_logs.location column

location Enum Not Validated Server-Side

VULNERABILITY

The location field accepted any string. A direct API call could store arbitrary text outside the five valid options shown in the UI.

REMEDIATION

Added CHECK constraint restricting location to: in-cab, parking-lot, planet-fitness, truck-stop, other.

LOW FIXED
meal_logs.meal_time, feedback.category columns

meal_time and feedback.category Enums Not Validated Server-Side

VULNERABILITY

Both columns accepted any string value at the database layer despite the UI restricting options via <select>.

REMEDIATION

Added CHECK constraints: meal_time IN (breakfast, lunch, dinner, snack) and category IN (general, workout, meal, glp1, gym-finder).

LOW ACCEPTED RISK
.env

Supabase Anon Key in .env

VULNERABILITY

The VITE_SUPABASE_ANON_KEY is a public-facing key by design — it is safe to embed in client-side code. Its permissions are entirely governed by RLS policies. The key is not a secret; it identifies the project, not an admin user.

REMEDIATION

No code change required. Ensure the service role key is never exposed. All sensitive access is blocked by RLS. Rotate the anon key via the Supabase dashboard if the project is public in version control.

Scope: This review covers RLS policies, database constraints, frontend input handling, XSS vectors in dynamically generated HTML, service worker caching behavior, and HTTP security headers. It does not cover server infrastructure, Supabase Edge Function secrets management, or third-party dependency audits.