Software Engineering / ENGINEERING CASE STUDY
Multi-Tenant SaaS Security Review & Launch Hardening
Security and UK GDPR review of an AI-generated, multi-tenant care-management SaaS before launch. Found an account-takeover path, permission checks voided on 14 tables, unauthenticated serverless functions, and stored XSS.
THE PROBLEM
Find the holes in AI-generated code before launch
The challenge
A UK social-care SaaS startup was heading to launch with a multi-tenant care-management app built from AI-generated code. It holds care records for several organizations, so one tenant must never reach another's data, and it has to hold up under UK GDPR.
My role
I ran the full security and UK GDPR review, then shipped the database fixes before launch.
What I did
- Split the review across four parallel, read-only AI reviewers: serverless functions, database, frontend, and privacy. Checks against production were read-only. No writes.
- Account takeover: a staff-admin function could change any member's login email or password with a weaker permission than changing their role required.
- Tenant row-level security policies had been created as PERMISSIVE instead of RESTRICTIVE. PostgreSQL ORs permissive policies together, so they silently voided the permission checks on 14 tables.
- Also found unauthenticated serverless functions and stored XSS in an email renderer.
The tradeoff
No writes against production meant no confirming a finding by trying the exploit. Slower, but live care records were never at risk. The lesson I paid for earlier: I once tightened a database policy after checking only the repo, and it silently broke an external automation that used the public key. It was restored before any data was lost. Now I list every consumer, including automation tools and other apps, before tightening access.
THE RESULT
All four issues were found before launch. I shipped the database access-rules pass and database-enforced two-step login for the Owner, Admin, and Manager roles before go-live.
PostgreSQL row-level security · Supabase · TypeScript · Deno · Claude Code
HAVE A SIMILAR CHALLENGE?