Vibe Code Security Scanner: Leaked API Keys, Supabase RLS avatar

Vibe Code Security Scanner: Leaked API Keys, Supabase RLS

Pricing

from $35.00 / 1,000 site scanneds

Go to Apify Store
Vibe Code Security Scanner: Leaked API Keys, Supabase RLS

Vibe Code Security Scanner: Leaked API Keys, Supabase RLS

Scan any app built with AI (Codex, Cursor, Claude Code, Lovable, Bolt, v0, Replit) by URL for leaked OpenAI, Claude, Gemini and 60+ other API keys, open Supabase tables, source maps and missing headers. A-F grade, fix prompts. $0.05/site.

Pricing

from $35.00 / 1,000 site scanneds

Rating

0.0

(0)

Developer

Magnova

Magnova

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Features

Limited permissions

Share

Vibe Code Security Scanner: leaked API keys, open Supabase tables, exposed source maps

Paste the URL of any app you built with AI (Codex, Cursor, Claude Code, Windsurf, Copilot, Lovable, Bolt, v0, Replit, Base44 or anything else) and get an A–F security grade in seconds. The scanner reads exactly what every visitor's browser downloads (your HTML, every JavaScript bundle and lazy-loaded chunk, and any public source maps) and tells you which secrets are leaking, whether your database (Supabase, Firebase, Base44, Appwrite, PocketBase, Convex, Hasura/Nhost or Parse) can be read by strangers, and how to fix each problem with a copy-paste prompt for your AI coding tool.

$0.05 per site scanned. No sign-up beyond Apify, no GitHub access, no code upload.

What it finds

CheckWhat it means for you
Leaked AI keys (any model)OpenAI, Anthropic (Claude), Google Gemini, xAI (Grok), Mistral, DeepSeek, Groq, OpenRouter, Perplexity, Cohere, Together, Fireworks, Cerebras, NVIDIA NIM, Hugging Face, Replicate, ElevenLabs, Deepgram, AssemblyAI, fal.ai, Azure OpenAI, Qwen, Kimi, Pinecone, LangSmith, Voyage and 30+ more. Keys with a known prefix are matched directly; prefix-less keys (Mistral, Cohere, DeepSeek...) are caught by the variable they are assigned to (VITE_MISTRAL_API_KEY = ...).
AI calls made from the browserFront-end code that calls api.openai.com, api.anthropic.com, generativelanguage.googleapis.com and 25+ other AI endpoints with an auth header, plus the dangerouslyAllowBrowser: true flag: a key is in the browser even when it is assembled at runtime.
Other leaked secretsStripe secret/restricted, Square, PayPal/Braintree, Polar, Razorpay, Shopify, Supabase service_role and sb_secret_, AWS, Google OAuth, GitHub, GitLab, npm, PyPI, Vercel, DigitalOcean, Doppler, PlanetScale, Sentry, Slack and Discord (tokens and webhooks), Telegram bots, SendGrid, Resend, Mailgun, Mailchimp, Brevo, Postmark, Twilio, Clerk, Notion, Airtable, Linear, Mapbox secret, PostHog personal keys, private keys, Postgres/MongoDB/MySQL/Redis connection strings, and high-entropy strings assigned to secret/token variables
Public-by-design keys (no false alarms)Stripe pk_, Supabase anon / sb_publishable_, Firebase web config and referrer-restricted Google Maps keys are labelled public by design with an explanation, instead of a scary "LEAK!"
JWT decodingEvery JWT is decoded so we can tell a harmless Supabase anon key from a catastrophic service_role key (role, project ref, expiry are shown)
Open Supabase tables (owner mode)Using only the anon key your app already ships, the scanner checks each table read-only and reports which ones anyone on the internet can read, with column names and sensitive-looking columns (email, phone, token, address). Works with legacy anon keys and new sb_publishable_ keys. Since 2026 Supabase hides the table list from public keys, so tables are found from your code, from GraphQL introspection when pg_graphql is on, from ~80 common table names, and from any names you add in extraTables. Private-looking Storage buckets (signed-URL or per-user folders) are flagged high. This is the Row Level Security mistake behind the 2025 Lovable data leaks
Open Firebase (owner mode)Realtime Database world-readable rules, Firestore collections left in test mode, Storage buckets anyone can list
Supabase alternatives (owner mode)Base44 entities, Appwrite collections (permissions granting any), PocketBase collections with an empty List rule, Convex public queries that return personal data, Hasura / Nhost GraphQL tables readable (or writable) without login, Parse / Back4App classes incl. _User, and Supabase Storage buckets whose file list is public. Endpoints, project IDs and table names are read from your own bundle
Smart severity (no false alarms)A readable table of blog posts or products is reported as low ("fine if it's meant to be public"); one with emails, phones, addresses, names or tokens, or named users/orders/payments/messages, is critical. Values are checked in memory only and never stored
Database & backend secretsSupabase service_role/sb_secret_/management tokens, Turso/libSQL tokens (JWT decoded: read-write vs read-only), Neon, Xata, Appwrite server keys, Convex deploy keys, Upstash/Vercel KV tokens, Nhost/Hasura admin secrets, InstantDB admin tokens, Parse master keys, Prisma Accelerate URLs, Firebase/Google service-account JSON, and app secrets like JWT_SECRET, NEXTAUTH_SECRET, AUTH_SECRET. Tutorial strings (postgres:postgres@localhost, [YOUR-PASSWORD]) are ignored
Exposed files (owner mode)/.env, /.env.local, /.env.production, /.git/config, /.git/HEAD, /.DS_Store, /backup.zip — confirmed by file signature, so single-page-app catch-all routes don't cause false positives
Source-map reconstructionPublic .map files are parsed, the original file names are listed (for example src/lib/supabase.ts) and the original source is scanned for secrets
Full bundle coverageFollows <script> tags, modulepreload links, Next.js build manifests and app-router chunks, and Vite/webpack lazy chunks — not just the first bundle
Security headersContent-Security-Policy, HSTS, X-Frame-Options / frame-ancestors, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, weak CSP, X-Powered-By
TransportHTTPS, HTTP→HTTPS redirect, TLS certificate validity and expiry, mixed content
Cookies and CORSSession cookies missing Secure/HttpOnly/SameSite, CORS that reflects any origin or allows * with credentials
Platform fingerprintLovable, Bolt, Replit, Base44, Vercel, Netlify, Cloudflare Pages, Firebase Hosting; Next.js, Vite, CRA, SvelteKit, Nuxt; Supabase, Firebase, Base44, Appwrite, PocketBase, Convex, Hasura, Nhost, Turso, Neon, Upstash, Xata, InstantDB, PlanetScale, Parse/Back4App, MongoDB, Prisma Accelerate, Fauna, Clerk

Fixes you can paste, not just warnings

Every finding comes with:

  • fixPlainEnglish — what is wrong and what to do, written for builders, not pentesters.
  • fixPrompt — a ready prompt for whatever AI coding tool you use (Codex, Cursor, Claude Code, Lovable, Bolt, Replit...), e.g. "Move every call to the AI provider into a server-side API route that reads the key from a server-only env var..."
  • fixConfig — the exact file to drop in: vercel.json, Netlify/Cloudflare _headers, next.config.js, firebase.json, Supabase RLS SQL, Firebase rules, or the Vite/Next setting that turns off public source maps.

Each site row also has a headerConfig with every missing header for your host in one snippet.

How to use it

  1. Put one or more app URLs in App URLs to scan. The homepage is enough.
  2. Leave I own these sites off for a passive scan of anything, or turn it on for your own apps to add the database and exposed-file checks.
  3. Click Start. Most sites finish in 2–30 seconds.

Input example

{
"urls": ["https://myapp.lovable.app"],
"iOwnThisSite": true
}

Output example (one row per site)

{
"url": "https://myapp.lovable.app",
"status": "ok",
"score": 18,
"grade": "F",
"critical": 2,
"high": 0,
"medium": 3,
"topIssue": "Supabase table 'profiles' is publicly readable (~1342 rows)",
"platform": "lovable",
"framework": "Vite",
"backends": ["Supabase"],
"jsFilesScanned": 12,
"sourceMapsFound": 0,
"findings": [
{
"severity": "critical",
"category": "database",
"title": "Supabase table 'profiles' is publicly readable (~1342 rows)",
"note": "Anyone with the public anon key can read this table... Sensitive-looking columns: email, phone.",
"fixPrompt": "Paste into Lovable: \"In Supabase, enable Row Level Security on the public.profiles table...\"",
"fixConfig": "alter table public.profiles enable row level security; ..."
},
{
"severity": "info",
"title": "Supabase anon key (public by design)",
"maskedEvidence": "eyJh...64p0 (208 chars)",
"publicByDesign": true,
"jwtClaims": {"role": "anon", "ref": "abcd...", "iss": "supabase"}
}
]
}

Try it on our deliberately vulnerable demo app (all keys are fake): the prefilled URL in the input.

Scan on every deploy (GitHub Action)

Add your Apify API token as the repository secret APIFY_TOKEN, then save this as .github/workflows/security-scan.yml. The build fails if any critical issue is found.

name: Vibe code security scan
on:
deployment_status:
workflow_dispatch:
jobs:
scan:
if: github.event_name == 'workflow_dispatch' || github.event.deployment_status.state == 'success'
runs-on: ubuntu-latest
steps:
- name: Scan deployed app
env:
APIFY_TOKEN: ${{ secrets.APIFY_TOKEN }}
APP_URL: ${{ github.event.deployment_status.environment_url || 'https://myapp.vercel.app' }}
run: |
curl -s -X POST "https://api.apify.com/v2/acts/magnova~vibe-code-security-scanner/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H 'Content-Type: application/json' \
-d "{\"urls\": [\"$APP_URL\"]}" > report.json
jq -r '.[] | "\(.grade) \(.score)/100 critical=\(.critical) high=\(.high) \(.url)"' report.json
jq -r '.[].findings[]? | select(.severity=="critical" or .severity=="high") | "- [\(.severity)] \(.title)"' report.json
test "$(jq '[.[].critical // 0] | add' report.json)" -eq 0

Monitor your apps on a schedule

  1. Create an Apify Schedule (daily or weekly) for this Actor with your app URLs.
  2. Pick a History store (any key-value store in your account, e.g. app-security-history).
  3. Turn on Only report new findings.

Each run marks findings as new or unchanged and lists fixedSinceLastScan, so you only hear about regressions. Connect the run to Slack, email or a webhook in the Actor's Integrations tab. You can also trigger it from a Vercel deploy hook or Netlify build hook via Apify webhooks / the run API above.

For agencies and builders with many apps

Put all your client apps in the urls list. Each site is one row with grade, counts and top issue, so the dataset's Security report view is a ready portfolio table. Export to CSV, Excel or Google Sheets.

Use with AI agents / MCP

The Actor has one required input and returns structured JSON, so Claude, ChatGPT, Cursor and other agents can call it through the Apify MCP server (mcp.apify.com) zero-shot:

{"urls": ["https://example-app.vercel.app"]}

Agents get grade, score, topIssue and findings[].fixPrompt, which they can apply directly to your codebase.

How much does it cost to scan a website for leaked API keys?

$0.05 per site scanned (pay per event, no start fee, no monthly rental). Higher Apify plans get automatic discounts (Silver 15% off, Gold and above 30% off). Invalid URLs, unreachable sites and sites skipped because of your spending limit are free. Scanning 100 apps costs $5.

Vibe Code Security Scanner API

Call it from any language through the Apify API: POST https://api.apify.com/v2/acts/magnova~vibe-code-security-scanner/run-sync-get-dataset-items?token=YOUR_TOKEN with the JSON input above. Python and JavaScript clients (apify-client) work too.

FAQ

How do I check if my Lovable app is secure?

Paste your *.lovable.app (or custom domain) URL, tick I own these sites, and run. The most important result is whether any Supabase table is publicly readable; the fix prompt tells Lovable exactly which RLS policies to add.

Does it work with Supabase alternatives like Appwrite, PocketBase, Convex or Base44?

Yes. Owner mode tests Base44, Appwrite, PocketBase, Convex, Hasura/Nhost and Parse/Back4App the same way it tests Supabase: it finds the endpoint and table names in your bundle, makes read-only requests without logging in, and tells you which data strangers can see, with a fix prompt for each. For Turso, Neon, Upstash, Xata, InstantDB, PlanetScale and MongoDB it catches leaked database URLs, tokens and admin keys.

Is my Supabase anon key a leak?

No. It is meant to be public, and the scanner labels it so. It is only dangerous when Row Level Security is off, which is what owner mode tests.

How do I know if my OpenAI, Claude or Gemini key is exposed?

Any OpenAI, Anthropic (Claude), Gemini, Grok, Mistral, DeepSeek, Stripe secret (sk_live_) or similar key found in your HTML, JavaScript chunks or source maps is reported as critical, with where it was found (file URL or original file name) and a masked value.

Does it attack my site?

No. Default mode only reads files a normal browser downloads. Owner mode adds a few read-only requests (one limit=1 read per table or collection on the backend your app uses, GraphQL queries only, Convex queries only, single GETs for files like /.env). It never writes, deletes, fuzzes, logs in or brute-forces anything, and never uses a secret key it finds.

Passive checks read only public files any visitor's browser receives. Owner mode is for sites you own or have written permission to test; you confirm that with the checkbox. Do not use it against systems you are not authorised to test.

Do you store my data?

Findings are written only to your own run's dataset. Secret values are masked (first and last 4 characters), database row values are discarded immediately (only column names are reported) and nothing is kept by us.

Why is my grade low when I'm on lovable.app or bolt.host?

On platform subdomains the platform controls response headers, so header findings there aren't your fault yet. They become yours to fix (with the provided config) once you move to a custom domain. Header issues are capped at 10 points, so a site whose only issues are missing headers still gets an A (90), and they never outweigh a real leak.

What does "inconclusive" mean?

If a database answers a read test in a way the scanner doesn't recognise (a server error, a rate limit, an unexpected response format), that check is reported as inconclusive, never as a pass. The result shows inconclusiveChecks above 0, allClear false, and a diagnostics list with only the backend name, a generic endpoint template, the HTTP status and the response shape. No data, URLs or keys are in it, so it's safe to paste into an issue. If a rescan gives the same result, please open an issue on this Actor's Issues tab with that diagnostics block and we'll fix support for your setup.

Can it miss things?

Yes. It sees the deployed front end, not your server code, private API routes or business logic (e.g. broken authorisation on /api/orders/2). Use it as a fast, repeatable first line, not a full penetration test.

Alternatives

Free web scanners give a one-off report in a browser tab. This Actor is built for automation: an API, bulk URLs, scheduled monitoring with new/fixed tracking, CI integration and MCP access for AI agents, at $0.05 per scan with no subscription.

  • Data source: only the public HTML, JavaScript, source maps and HTTP headers that the target site serves to any visitor; owner-mode probes use only keys the site itself publishes, read-only.
  • Authorisation: owner-only checks require the user to confirm ownership or permission (iOwnThisSite). Scanning localhost and private network addresses is blocked.
  • Privacy: secrets are masked; database row contents are never output or stored; no personal data is collected.
  • The user is responsible for having permission to test the sites they scan.