Compound Labs
Menu
Get the newsletter
THE STANDUPHIGH: @rsdoctor/rspack-plugin: Unauthenticated API Exposes Source CodeSOURCE CODE, NO AUTHFOUNDER BLUESKYCodex now checks stated times against the clockFOUR MINUTES OFF THE CLOCKFRONTWIREFront Wire now matches memberships to exact email addressesEXACT EMAIL MATCHCOMPOUNDYetone/magpie: Shared model control for Codex and Claude CodeSHARED MODEL CONTROLCOMPOUND FACEBOOKCompound Labs' deploy check excludes nightly output from change reportsNIGHTLY OUTPUT, EXCLUDEDSTOREREADYStoreReady evaluates AI mobile app builders against App Store review evidenceFOUR VERDICTS, SOURCED EVIDENCEAGENTWIREBrowserbase Stagehand: SDK for coding agents on any websiteSDK FOR CODING AGENTSCOMPOUND BLUESKYCompound Labs' deploy guard now accepts the declared generated fileGENERATED FILE, NOW ACCEPTEDSTACKTABStackTab embeds its price table with one dependency-free iframeONE IFRAME, ZERO DEPENDENCIESAGENTWIREdbt-mcp: MCP server for interacting with dbtMCP SERVER FOR DBTCOMPOUND TELEGRAMWireCall rate-limits new device keys and returns 429 responses when blockedFIVE DEVICES, THEN 429TOOLDRIFTToolDrift ranks AI coding models by measured usage across toolsMEASURED USAGE RANKS MODELSCOMPOUNDMikehasa/golive-skill: Open-source CLI for agent-safe deploymentsAGENT-SAFE DEPLOYMENTSFOUNDER PEERLISTAgentWire now includes entry images in its daily agent-tool emailsIMAGE FIELDS NOW PASSEDPOPWIREPopwire sends each story's finished card in its daily digestEACH STORY, ITS OWN CARDAGENTWIREBrowserCash/teracrawl - LLM web crawler API for clean MarkdownWEB CONTENT, CLEAN MARKDOWNCOMPOUND BLUESKYCompound Datasets now records each dataset's cut date from its files145,791 ROWS, CUT DATES ADDEDPOLICYDRIFTPolicyDrift checks privacy claims against deployed routesCACHE FIRST, ROUTES VERIFIED
Independent product R&D labFounded and run by Isaiah Kim, @kyisaiah47Newest commit Sep 24, 2026, ToolDriftNewest writing Sep 24, 2026Site changelog Sep 25, 2026
Sections
Sep 24, 20262 min read

BreachProbe finds database leaks in shipped apps

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.
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/
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
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;
+}
BreachProbe, Method: BREACHPROBE / METHOD How a finding is proved Every finding on a report is something this scanner did to the app and read
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
BreachProbe, Pricing: BREACHPROBE / PRICING Pricing The scan and the score are free. The two paid tiers are one-off payments, the full report

All writing

Alongside