I shipped 8 BaaS security scanners on Apify in 9 days — here's the pattern that lets one developer compete with bigger publishers
Two weeks ago I noticed that the Apify Store had zero security scanners for any of the popular Backend-as-a-Service platforms. Not one. Search for "supabase security" or "firebase security" or "strapi security" and the results were a mix of unrelated scrapers and outdated forks.
The market gap was screaming at me. Every BaaS makes the same architectural promise: "your data is private because we have role-based access control." And every BaaS makes the same operational mistake: most developers leave at least one collection or table readable to anonymous users in production.
Across 100+ projects I've audited:
- 22% of Supabase projects leak data anonymously (RLS forgotten on at least one table)
-
23% of Firebase projects have
firestore.ruleswithif trueor expired test-mode rules -
Strapi templates ship with Public-role
findenabled — the warning to disable is rarely seen -
Directus Public-role read on
directus_usersexposes hashed passwords and tokens - PocketBase, Appwrite, Nhost, Payload CMS — same story, different syntax
So I built a scanner for each one. Eight in nine days. All public on Apify. All free to run. Each one converts to a $99 turnkey "I'll fix it for you" service that I do off-platform via Stripe.
Here's the pattern that let me ship that fast.
The single-file scanner template
Every BaaS exposes a public REST endpoint per collection/table. The probe is always the same shape:
async function probe(url, collection) {
const probeUrl = `${url}/<api-path>/${encodeURIComponent(collection)}?<limit-1-param>`;
try {
const r = await fetch(probeUrl, { signal: AbortSignal.timeout(8000) });
if (r.status === 200) {
const j = await r.json();
const total = extractTotal(j); // varies per BaaS
const sampleCols = extractSampleColumns(j); // varies per BaaS
return { exists: true, readable: true, total, sampleCols };
}
if (r.status === 403 || r.status === 401) return { exists: true, readable: false };
return { exists: false };
} catch (e) {
return { exists: false, error: e.message };
}
}
The differences per BaaS are surgical:
| BaaS | API path | Limit param | Count source |
|---|---|---|---|
| Supabase | /rest/v1/{table} |
Range: 0-0 (header) + Prefer: count=exact
|
Content-Range header |
| Strapi v4+ | /api/{collection} |
pagination[limit]=1 |
meta.pagination.total |
| Strapi v3 | /{collection} |
_limit=1 |
data.length (no total) |
| Directus | /items/{collection} |
limit=1&meta=total_count |
meta.total_count |
| Payload CMS | /api/{collection} |
limit=1 |
totalDocs |
| PocketBase | /api/collections/{name}/records |
perPage=1 |
totalItems |
| Nhost (Hasura) | POST /v1/graphql
|
_aggregate { count } |
data.X_aggregate.aggregate.count |
| Appwrite | /v1/databases/{db}/collections/{c}/documents |
?limit=1 + X-Appwrite-Project header |
total |
| Firebase Firestore | /v1/projects/{p}/databases/(default)/documents/{c} |
pageSize=1 |
(returns docs directly) |
That's it. Same shape, 60-90 minutes to write the next one once the first is done.
The leverage: shared HTML report renderer + CTAs
Each scanner produces JSON dataset rows AND an HTML report saved to the run's key-value store. Same HTML renderer, parameterized per BaaS. Each report ends with:
- Severity-color-coded findings table (critical/high/medium/low)
-
curlreproducer per finding — the exact request an attacker would make -
Paste-ready fix code specific to the BaaS (SQL
ALTER TABLE ENABLE ROW LEVEL SECURITY, or rules-file diff, or admin-panel click path) - CTAs: turnkey $99 fix offer, $29/mo continuous auto-scans, and the open-source CLI
Every report ends with: "Solo dev competing with bigger publishers — a 30-second review on Apify is the single thing that lifts ranking. Thank you." That last line is what makes reviews actually happen.
The "demo mode" trick that 10x'd conversion
Apify Store visitors hit the actor page, see the input fields, and bounce 80% of the time when they realize they need to paste in their project URL + an anon key just to see what the report looks like.
The fix: remove required from the input schema and add a demo branch at the top of main.js:
if (!supabaseUrl || !anonKey) {
console.log('🎬 DEMO MODE: No project URL/key provided. Generating sample report.');
const demoReport = { /* hardcoded plausible findings */ };
// ... render HTML with a yellow "DEMO" banner up top
return;
}
Now anyone can hit "Run" with zero input and immediately see what a real scan returns — with full severity table, sample sensitive columns, copy-pasteable fix snippets, and CTAs. The Run button always succeeds and always educates.
This single change made the actor genuinely viral-able. You can paste the actor URL in a Slack/Discord/forum and the recipient gets value in 3 seconds without any commitment.
The 8 actors
- Supabase RLS Scanner
- Firebase Security Auditor
- Strapi Security Scanner — new
- Directus Security Scanner — new
- Payload CMS Security Scanner — new
- PocketBase Security Scanner
- Appwrite Security Auditor
- Nhost Security Scanner
Each one is the only scanner of its kind in the Apify DEVELOPER_TOOLS category as of today. That's the whole point — competing on undefended ground.
What's next
I'm building Convex and Xata scanners next. After that I'll likely stop adding new ones and focus on:
- One blog post per BaaS showing a real (anonymized) leak I found in the wild
-
GitHub code-search outreach — F5Bot alerts me when someone commits an
anon keyin public; I send them the scanner link - A "BaaS leak registry" open-source page indexing known-bad patterns per platform
If you build on any of these BaaS, run the scanner on your own project. The demo mode means you can see the report shape first. Most projects don't leak, but the 22% that do mostly don't know yet.
If you publish to Apify Store yourself: the demo mode pattern is a free 10x to your run-button conversion. Took me too long to figure out — saving the next person that time.
Renzo, solo developer in Lima, Peru. I scan, write, and ship security tools at the intersection of "I should automate this" and "let me publish it as a product." Open source: @perufitlife/supabase-security.
If you found this useful, a follow on dev.to helps a solo developer keep shipping. Or just leave a review on any of the 8 scanners — reviews are the single biggest lever a new Apify publisher has.
Top comments (0)