What we check and fix (17 items)

On paid plans, with the owner's consent, PatchAndShip checks six areas: Row Level Security on every table, storage bucket policies, secret keys in the client bundle and repository history, secrets in public environment variables, the Supabase auth Site URL and redirect allow-list, and, on Fix & Deploy, the production build, domain, SSL and core flows.

The six areas

On paid plans, after you consent:

  • RLS, on every table. Supabase Row Level Security (RLS): switched on for every table, with policies so each user can reach only their own rows.
  • Storage, private buckets. Private buckets for private files, with access policies.
  • Exposed keys, out of the bundle. We scan the shipped JavaScript bundle and repo history for service_role keys and other secrets, remove them and tell you exactly which keys to rotate.
  • Env vars, secrets out of public variables. Secrets moved out of public (for example VITE_) variables. With Fix & Deploy we also set them on the host.
  • Auth redirects (fixed on Fix & Deploy). We check the Supabase Site URL and redirect URLs on every paid plan; with Fix & Deploy we point them at production instead of the preview. On Security Fix, any change is listed as a to‑do in your report.
  • Deploy, domain and SSL (Fix & Deploy only). Env vars on the host, custom domain with SSL, build fixes, and a smoke test of login, signup and your core flow. The Fix & Deploy package ($249) deploys one app to Vercel or Netlify, or keeps a Lovable or Replit app on that platform's own hosting with your domain. Each order covers one app, one Supabase project (or one Node app) and one deploy target.

Node/Express backends: missing server‑side access checks, open CORS and hard‑coded secrets; these are fixed, but they are not “critical” for the 48‑hour guarantee.

What the guarantee covers

Security Fix: every critical issue on our checklist fixed within 48 hours of working access. Fix & Deploy: fixed and live on your host within 48 hours. Otherwise, a full refund if you ask within 14 days of purchase. “Critical” means only the issues on our published checklist: Row Level Security (RLS) disabled or misconfigured, public storage buckets holding private files, exposed secret keys (in the client bundle, repo or public env variables), and, on Fix & Deploy only, misconfigured environment variables or auth redirects.

Full terms: Refund Policy.

The 17 items

These 17 items are what we check and fix, within your plan's scope (items 14 to 17 on Fix & Deploy only). Only the issues our Refund Policy defines as “critical” are covered by the 48‑hour guarantee, and they differ by package:

  • Security Fix: Row Level Security (RLS) disabled or misconfigured, public storage buckets holding private files, and secret keys exposed in your client bundle, repo or public env variables.
  • Fix & Deploy: Row Level Security (RLS) disabled or misconfigured, public storage buckets holding private files, exposed secret keys, and misconfigured environment variables or auth redirects. “Live” means deployed to production on the host you chose for your order.

SECURITY DEFINER leaks (item 6) and the Node/Express items (9 to 13) are fixed, but they are not “critical” for the 48‑hour guarantee. Full terms: Refund Policy.

Supabase‑backed apps (Lovable, Bolt, Cursor, Replit with Supabase)

  • 1. Row Level Security disabled on tables in API‑exposed schemas
  • 2. Permissive RLS policies (USING (true) or open writes) on non‑public data
  • 3. Public storage buckets (and broad list or upload policies) for private files
  • 4. Secret or service_role keys in the client bundle or repo
  • 5. Other secrets under public env prefixes (VITE_*, NEXT_PUBLIC_*)
  • 6. SECURITY DEFINER views or RPCs callable by anon that expose private data
  • 7. Auth Site URL or redirect allow‑list not set for production (customer‑assisted when our Supabase role can't change it; fixed on Fix & Deploy, a to‑do in your report on Security Fix)
  • 8. Misconfigured environment variables that block secure production operation (a secret on the client, or a missing server env on the host; host env vars are set on Fix & Deploy only)

Node/Express‑style apps (typical Replit or Cursor backend)

  • 9. Missing server‑side authentication or ownership checks on private routes (IDOR, open admin, open destructive methods)
  • 10. Open CORS that reflects any Origin with credentials
  • 11. Secrets hard‑coded or committed; Replit Secrets not used
  • 12. Missing security headers or insecure session cookies (not “critical” for the 48‑hour guarantee)
  • 13. Server not bindable for publish (localhost only, or the wrong port)

Fix & Deploy only

  • 14. Production build failures we can fix without a rewrite
  • 15. Single‑page app deep‑link 404s (missing catch‑all rewrite)
  • 16. Custom domain and SSL, when you control DNS and apply our records (waiting on DNS pauses the clock)
  • 17. Smoke test of signup, login, the password‑reset landing page and one named core flow

Why these matter (from vendor docs)

  • Supabase's Security Advisor flags RLS disabled on a public table (lint 0013, level ERROR): Anyone with your project URL can read, edit, and delete all data in this table because Row‑Level Security is not enabled. (Supabase Docs: Database Advisors)
  • Supabase: grants control whether a role can reach an object, RLS controls which rows it can access. Use both controls for every exposed object. (Supabase Docs: Securing your API)
  • Supabase Storage buckets are private by default. For a public bucket, anyone who possesses the asset URL can readily access the file. Supabase's examples are profile pictures, public media and blog content. (Supabase Docs: Storage Buckets)
  • Supabase: A secret key bypasses every Row Level Security policy you have. Never put one in a browser, a shipped application, or source control. Publishable and anon keys are designed to be public. (Supabase Docs: API keys)
  • Supabase is deprecating the anon and service_role keys by the end of 2026, in favor of sb_publishable_ and sb_secret_ keys. (Supabase Docs: API keys)
  • Vite docs: Variables prefixed with VITE_ will be exposed in client‑side source code after Vite bundling. And: VITE_* variables should not contain sensitive information such as API keys. (Vite Docs: Env Variables and Modes)
  • Supabase: change the Site URL from http://localhost:3000 to your production URL. It is critical for email confirmations and password resets. In production, Supabase recommends setting the exact redirect URL rather than wildcards. (Supabase Docs: Redirect URLs)
  • Vercel: in a Vite single‑page app, deep linking won't work out of the box. You need a catch‑all rewrite to /index.html in vercel.json. (Vercel Docs: Vite on Vercel)
  • Replit: a published web server must listen on 0.0.0.0. Listening only on localhost or 127.0.0.1 does not work for published apps. Secrets set in the editor do not automatically carry over to your published app. (Replit Docs: Troubleshoot publishing)
  • Supabase's changelog says that once the change reaches a project, new tables you create in public schema require an explicit opt‑in (via a Postgres grant) before the Data API can see them. The Data API is Supabase's auto‑generated REST and GraphQL layer. Existing tables keep their current grants and stay reachable, RLS behavior is unchanged, and apps that only use a direct Postgres connection are not affected. (Supabase changelog)
  • Supabase's planned timeline: from May 30, 2026, the new behavior became the default for new projects, rolled out gradually. From October 30, 2026, Supabase plans to apply it to all existing projects. As of October 14, 2026, that step has not happened yet. (Supabase changelog)
  • When a grant is missing, the Data API returns error 42501, permission denied for table your_table. (Supabase changelog)
  • Supabase's recommended fix treats the grant, enabling RLS and the policies as one unit. If the grant is missing, Postgres rejects the query before RLS comes into play. (Supabase changelog)

Vendor quotes last verified: .

What the free check covers

PatchAndShip's free mini check is passive: it looks only at the public homepage, its scripts and its security headers (for exposed secret keys, missing headers and publicly listed storage links), and nothing else: no database queries, no logins, no changes. It returns a one‑page summary within 24 hours. The app owner (or an authorized person) must consent. The signed‑out test of your live app is part of paid orders only.