01 Sample report

Sample
not a client report

This is what €299 buys.

Below is a sample of the audit report format, populated with the issues we most commonly find in Lovable, Bolt and v0 apps, so you can judge the depth before you pay. It is a sample of the format, not a real client's report. Client reports are confidential.

Audit report: sample

Fee
€299
Turnaround
48 hours typical
Findings shown
5 of a typical 8–15
Format
severity-ranked, written

02 The findings

Five findings, ranked by severity.

Each one names the problem, why it matters, the concrete fix, and the effort to fix it. Real reports typically run 8–15.

Sample findings

Critical · Auth

The Supabase tables holding user profiles and orders have RLS off. Any visitor with the public anon key, which ships in your frontend bundle by design, can read and modify every row via the auto-generated REST API.

  • Fix Enable RLS on all tables; add per-user policies (auth.uid() = user_id); verify with an anonymous-role test suite.
  • Effort 4–6 h

Critical · Secrets

The Supabase service-role key (bypasses RLS entirely) appears in commit history from an early .env commit. Deleting the file later does not remove it from history.

  • Fix Rotate the key immediately; purge history (git filter-repo) or rotate + accept history; move secrets to platform env vars; add secret scanning to CI.
  • Effort 2–3 h

High · Payments

The app shows "Payment successful" based on the client-side redirect alone. There is no webhook verifying the Stripe event, so a user can reach the paid state without a completed charge, and real failed payments look identical to successes.

  • Fix Implement the checkout.session.completed webhook with signature verification; gate paid features on the verified server-side state.
  • Effort 4–8 h

High · Error handling

Unhandled exceptions in API routes return full stack traces (file paths, query fragments) to the browser: useful reconnaissance for an attacker, confusing for users.

  • Fix Add a global error boundary on API routes: log the full error server-side, return a generic message with a correlation ID.
  • Effort 2–4 h

Medium · Monitoring

There is no way to know the app is broken until a customer emails. No Sentry/uptime check, no alerting, and "production" shares a database with preview deployments.

  • Fix Add Sentry (or similar) + a free uptime monitor; separate the production database from previews; alert to email.
  • Effort 2–3 h
01 Critical · Auth

The Supabase tables holding user profiles and orders have RLS off. Any visitor with the public anon key, which ships in your frontend bundle by design, can read and modify every row via the auto-generated REST API.

  • Fix Enable RLS on all tables; add per-user policies (auth.uid() = user_id); verify with an anonymous-role test suite.
  • Effort 4–6 h
02 Critical · Secrets

The Supabase service-role key (bypasses RLS entirely) appears in commit history from an early .env commit. Deleting the file later does not remove it from history.

  • Fix Rotate the key immediately; purge history (git filter-repo) or rotate + accept history; move secrets to platform env vars; add secret scanning to CI.
  • Effort 2–3 h
03 High · Payments

The app shows "Payment successful" based on the client-side redirect alone. There is no webhook verifying the Stripe event, so a user can reach the paid state without a completed charge, and real failed payments look identical to successes.

  • Fix Implement the checkout.session.completed webhook with signature verification; gate paid features on the verified server-side state.
  • Effort 4–8 h
04 High · Error handling

Unhandled exceptions in API routes return full stack traces (file paths, query fragments) to the browser: useful reconnaissance for an attacker, confusing for users.

  • Fix Add a global error boundary on API routes: log the full error server-side, return a generic message with a correlation ID.
  • Effort 2–4 h
05 Medium · Monitoring

There is no way to know the app is broken until a customer emails. No Sentry/uptime check, no alerting, and "production" shares a database with preview deployments.

  • Fix Add Sentry (or similar) + a free uptime monitor; separate the production database from previews; alert to email.
  • Effort 2–3 h

03 The structure

What every report contains.

From Etherlabz, the audit desk

Re What every audit report contains

cf. 01

Plain language first, then severity

Every report opens with an executive summary in plain language, then severity-ranked findings: what broke, why it matters, how to fix it, and the effort involved.

cf. 02

It ends with a number

Every report closes with a fixed-price quote to fix the criticals. Most apps fit the €990 critical fix sprint, and the €299 audit fee is credited.

cf. 03

A "fine as-is" list

A list of what we checked and did not flag, so you know what you are not paying to fix.

Five findings shown here. Real reports typically run 8–15.

Entry: closing

The same format, filled in with what's actually broken in your app.

Balance due one conversation

Now booking