DEV Community

Cover image for BreachProbe finds database leaks in shipped apps
Compound Labs
Compound Labs

Posted on Originally published at thecompound.tech

BreachProbe finds database leaks in shipped apps

breachprobe.thecompound.tech

Security checks can return a clean result even when the check itself cannot reach what it tests. Commit 2a513f7 fixed that in BreachProbe by proving Supabase JWT signing secrets with HMAC verification and adding seven cases to the deploy check.


BreachProbe

The scan console

The console accepts one app URL and labels the scan read-only. It shows that no account or installation is required, then lists the checks in order.

The scan reads shipped JavaScript, probes Supabase REST endpoints, checks response headers, looks for broken-auth patterns, inspects Stripe routes, and creates two signed-in test accounts for cross-tenant checks.

BreachProbe, The main console: SAMPLE demo-app.lovable.app ยท THE WORKED EXAMPLE, SCORED BY THE ENGINE demo-app.lovable.app scored out of 100, grade F.

The sample report

The sample report shows a scored app with a grade, severity totals, issue titles, evidence locations, and written fixes. Its critical finding reports cross-tenant reads across three tables from two signed-in users.

The report turns that finding into a policy change using auth.uid() and the affected owner column, then tells the reader to rerun the scan.

BreachProbe, Sample report: The subject is invented. Every check id, title, severity and fix on this page is the engine's own, printed from src/lib/

Every check

The checks page lists real check IDs, titles, severities, and whether each check carries a written fix. The console currently exposes 33 issue types and 32 written fixes.

The list separates shipped-code checks, response-header checks, Supabase REST checks, signed-in-user checks, and Stripe-route checks so the source of each verdict stays visible.

BreachProbe, Every check: 01 Start at 100. 02 Each critical takes 40, each high 22, each medium 10 and each low 4. 03 Each further finding in the

The method page

The method page explains what each probe sends and what answer counts as proof. It states that JWT candidates are checked against the app's own public anon key instead of being reported from string shape alone.

The signing-secret verifier recomputes the HS256 signature:

+function signs(jwt: string, secret: string): boolean {
+  const i = jwt.lastIndexOf('.');
+  if (i < 0) return false;
+  const signingInput = jwt.slice(0, i);
+  const given = jwt.slice(i + 1);
+  const want = crypto.createHmac('sha256', secret)
+    .update(signingInput).digest('base64')
+    .replace(/\+/g, '-').replace(/\//g, '_')
+    .replace(/=+$/, '');
+  return want === given;
+}
Enter fullscreen mode Exit fullscreen mode

BreachProbe, Method: BREACHPROBE / METHOD How a finding is proved Every finding on a report is something this scanner did to the app and read

The failed-scan state

The scan bar keeps its four operating terms visible when a scan fails: no account, nothing installed, read-only, and one URL. The error appears on its own row beneath them.

Commit 291abad changed this state after the error message displaced those terms. The same commit moved the demo destination to the sample report so the console's worked example opens from the scanner surface.

BreachProbe, Pricing: BREACHPROBE / PRICING Pricing The scan and the score are free. The two paid tiers are one-off payments, the full report

Top comments (0)