# ShipLatch > ShipLatch is a security scanner for "vibe-coded" web apps built with AI tools such as Lovable, Bolt.new, Replit, Cursor and v0, especially apps on Supabase or Firebase. A free passive scan finds leaked API keys, exposed .env and .git files, missing security headers and risky backend setups, with a plain-English explanation of each risk. Paid plans add copy-paste fix prompts for your AI builder, an ownership-verified, read-only deep scan of Supabase Row Level Security and Firebase rules. Contact: hello@shiplatch.com. X: @shiplatchhq. ## What the free scan checks - Fetches the public page plus up to 20 scripts it loads, like a browser, fetches up to 3 same-origin source maps, and makes one GET each to a short list of files that should never be public (/.env and variants, /.git/HEAD, /.git/config, /.DS_Store, supabase/config.toml, firebase.json, .replit and similar). HTML fallback pages never count as exposed. - Detects leaked secrets in HTML/JS: OpenAI, Anthropic, Stripe secret/restricted keys, AWS, GitHub, Slack, SendGrid, Resend, Twilio, private keys, Supabase service_role and sb_secret_ keys. - Detects AI provider keys (OpenAI, Anthropic, OpenRouter, Groq, xAI, Hugging Face, Replicate, Perplexity, ElevenLabs), Google keys (rated high when used with Gemini), and secret-looking values in VITE_/NEXT_PUBLIC_/EXPO_PUBLIC_/REACT_APP_ variables, including inside public source maps. - Flags exposed /.env and /.git, missing security headers (CSP, HSTS, X-Frame-Options/frame-ancestors, nosniff, referrer policy), permissive CORS and public source maps. - Detects the builder and whether the app uses Supabase or Firebase. - Passive and read-only: no logins, form submissions or exploitation. Refuses IP addresses and localhost. Rate limit: 20 scans per IP per hour. ## Newer checks (version and dev-mode detection, no exploit testing) - Vite dev server in production: flags a live site that is serving the Vite dev client instead of a production build. Presence only: we don't read the Vite version or test the known dev-server file-read bugs. (check id: vite-dev-server-exposed) - Outdated Next.js: reads the Next.js version the site already ships to the browser and flags versions below 16.4.1 (16.x) or 15.5.28 (15.x and older), which have published security fixes. Version detection only: we can't see whether the affected features are used. (check id: nextjs-outdated-security) - Gemini AQ. keys: flags new-format Gemini API keys (starting AQ.) in your page, JavaScript or public source maps. Key-format detection only: we never use or test a key. (check id: gemini-auth-key) - Outdated PHP ("php2shell", CVE-2026-109618 and CVE-2026-109619): reads the PHP version from the X-Powered-By header and flags versions below 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35 on their branch, and PHP 8.1 or older as end of life. Version detection only: distro-packaged versions are reported as info, and we never test the bug. CISA added PHP2Shell to its Known Exploited Vulnerabilities catalog on Oct 26, 2026; researchers have also recorded working shells on unpatched honeypots. (check id: php-outdated-security) - Lovable API keys: flags keys starting lov_ in your page, JavaScript or public source maps, only when Lovable-API-Key or api.lovable.dev appears within about 200 characters (Lovable's docs say these keys must never be in browser code). Key-format detection only: we never use or test a key. (check id: lovable-api-key) - Outdated WordPress ("wp2shell" CVE-2026-63030, and CVE-2026-87902): reads the WordPress version the homepage already advertises (generator tag and core script versions) and flags versions below their branch's fixed release (7.1.4 on 7.1, back to 4.7.37 on 4.7), and versions older than 4.7 as end of life (High). A second table flags versions missing the Oct 28, 2026 core-update fix (7.1.4 on 7.1, back to 4.7.39 on 4.7) as Medium when no High tier matched: no CVE yet, not on CISA's exploited list, attempts seen by Wordfence, no successful break-ins reported. Every tier's update target is the Oct 28 release for the branch. Version detection only: we never request the WordPress API, admin, feed or readme, nor wp-content/upgrade/ or setup-config.php, and we never test the bug. (check id: wordpress-outdated-security) - Known-vulnerable front-end libraries: flags known-vulnerable versions of 12 common front-end libraries (RetireJS data, Apache-2.0) when the page or its JavaScript advertises the version (a CDN link, file name or license comment). In minified bundles with no comment left (e.g. Vite 8), a version is reported only as a possible match ("may be"), when the library's own exact version string sits inside that library's known minified code; never inferred from minified code alone. Report-only: not graded, at most Medium. Version detection only: no extra requests, and we never test the bug. A clean result doesn't prove your libraries are current. (check id: vulnerable-js-lib) - Baseten API keys: flags keys in the current Baseten format (b10_, matching the pattern Baseten publishes for secret scanners) in your page, JavaScript or public source maps, with a guard for Baseten's docs placeholder. Report-only for now: shown as "looks like" and not counted in the grade. Keys created before October 1, 2026 have no prefix, so we can't see those. Key-format detection only: we never use or test a key. (check id: baseten-key) - Zapier, Make and n8n webhook URLs: flags automation trigger URLs (hooks.zapier.com/hooks/catch/, hook.make.com, and /webhook/ paths on n8n hosts) in your page, JavaScript or public source maps. Detection only: we never call a webhook, and the report hides the account, hook id and path. Report-only: shown on the report, not graded yet. (check id: zapier-webhook) - Next.js dev server in production: flags a live site whose page carries Next.js development build markers (next dev). Presence only: we read only the page we already fetch and send no extra requests. Medium, report-only: shown on the report, not graded yet. (check id: nextjs-dev-server-exposed) - Reflected CORS origin: flags a server that copies any Origin into Access-Control-Allow-Origin with credentials allowed. Header check only: one plain GET of your homepage with a made-up test Origin, no cookies, no body. Report-only: shown on the report, not graded yet. (check id: cors-origin-reflected) - Public .npmrc and Docker Compose files: one GET each to /.npmrc, /docker-compose.yml and /compose.yaml, content-checked. Detection only: a registry login is reported without showing any part of it, and we never use it. Report-only: shown on the report, not graded yet. (check id: npmrc-exposed) - ElevenLabs API keys: flags keys in the current ElevenLabs format (sk_ followed by 48 hex characters, including region-residency keys) in your page, JavaScript or public source maps, only when ElevenLabs or the xi-api-key header name appears in the same file. Key-format detection only: we never use or test a key. Older keys without the sk_ prefix are not covered. (check id: elevenlabs-key) - DebugBear RUM script: flags a page that loads DebugBear's RUM script (a cdn.debugbear.com script tag, inline loader, preload or a loader in your own JavaScript). DebugBear had a security incident on Oct 29, 2026 and told all RUM customers to remove the embed. DebugBear says attackers changed its DNS records through its domain registrar. DebugBear believes one customer was targeted, but it hasn't said the domain is safe again. Fix: remove it and redeploy. High while the incident is open. Presence only: we read only what we already fetched and never download or run the script. Plain links don't count. (check id: debugbear-rum-script) - Composio API keys: flags Composio agent-tool keys in your page, JavaScript or public source maps: user keys (uak_ + 43 characters) anywhere, and project or organization keys (ak_ / oak_ + 20 characters) only when Composio is named in the same file, with a guard for docs placeholders. Critical and counted in the grade; titles say "looks like" because a key-shaped string can still be a dead or test key. Key-format detection only: we never use or test a key. (check id: composio-key) - Infisical service tokens: flags Infisical service tokens (st..) in your page, JavaScript or public source maps. Medium, report-only for now: shown as "looks like" and not counted in the grade. Key-format detection only: we never use or test a token. (check id: infisical-service-token) - AI SDK in the browser: notes OpenAI, Anthropic or Groq SDK code that sets dangerouslyAllowBrowser to true in your page, JavaScript or public source maps (the SDKs' own warning text is skipped). Detection only: read from files the scan already fetched, 0 extra requests. Info, not graded: if the SDK uses your own API key, it may be readable by anyone, but bring-your-own-key apps and proxy setups use this legitimately. (uncounted Info note, not one of the checks; id: ai-sdk-browser-key) ## Pricing - Grading: results whose only issues are missing security headers max out at B and get a free copy-paste header fix (Vercel, Netlify, Cloudflare Pages). C or worse means a real exposure such as a leaked key, an exposed file or .git, public source maps or open CORS. - Free scan: $0. Grade, every finding and its risk; full report by email. Free re-scans of the same site every 24 hours. - Fix Pack: $29 one-time. Copy-paste fix prompts for every finding, an ownership-verified deep scan for one app (read-only Supabase RLS probe that requests zero rows and reads only row counts, plus Firebase rules checks) and 2 re-scans. Includes 30 days of monitoring (a daily automatic re-scan and an email if it gets worse). - Stay Locked: $15/month, cancel anytime. Everything in the Fix Pack (including fix prompts), unlimited re-scans of one app. An independent scan on every deploy; we alert you if the grade drops (deploy hook URL for Vercel, Netlify or GitHub Actions, plus an automatic daily re-scan; email only when the grade drops or a new critical/high/medium finding appears). - Fix Pack refunds: it's delivered instantly, so it isn't refundable once delivered, except for (a) a duplicate or mistaken charge, (b) you can't verify you own the app (full refund if you email us within 14 days and verification hasn't succeeded), or (c) the deep scan can't run because of a failure on our side that we don't fix within 7 days of your report. Refunds required by law are always honored. Terms §9: https://shiplatch.com/terms#section-9 - Guard Kit (free, https://shiplatch.com/guard-kit): copy-paste gitleaks setup (pre-commit hook + GitHub Action) to stop secrets reaching git. Included as a free extra with Stay Locked. - Ownership verification: a meta tag, a /.well-known/shiplatch.txt file, or a DNS TXT record (shiplatch-verify=). - Ebook "App Security for Vibe Coders": $9 one-time PDF. Pre-launch security playbook for Lovable, Bolt, Cursor and Replit apps (18 chapters, 47 pages, checklist, copy-paste prompts). https://shiplatch.com/ebook ## Limits ShipLatch is an automated point-in-time check, not a penetration test, code review or compliance audit. Only scan sites you own or are authorized to test. ## Key pages - [Scan your app (free)](https://shiplatch.com/) - [Pricing](https://shiplatch.com/#pricing) - [FAQ](https://shiplatch.com/#faq) - [All security guides](https://shiplatch.com/guides) - [Ebook: App Security for Vibe Coders ($9 PDF)](https://shiplatch.com/ebook) - [Newsletter](https://shiplatch.com/newsletter) - [Terms of Service](https://shiplatch.com/terms) - [Privacy Policy](https://shiplatch.com/privacy) - [Full text for LLMs](https://shiplatch.com/llms-full.txt) ## Free tools - [Is my .env file public?](https://shiplatch.com/tools/is-my-env-public): Check if anyone can download the .env file from your live site. Free, passive, one URL. For Lovable, Bolt, Replit, Cursor and Vite apps. - [Did I ship a dev server?](https://shiplatch.com/tools/did-i-ship-a-dev-server): Check if your live site is running the Vite dev server instead of a production build. Free, passive, one URL. No exploit testing. - [Is your Supabase app exposing more than it should?](https://shiplatch.com/tools/supabase-exposure-check): Free check for Supabase apps: is a key that bypasses Row Level Security in your public code? Plus a one-minute self-test for your tables. ## Use ShipLatch from your AI assistant (MCP) - [ShipLatch MCP server](https://shiplatch.com/mcp): free remote MCP server at https://shiplatch.com/mcp (Streamable HTTP, no sign-in). Tools: scan_url, get_scan, list_checks. Returns the free view only (grade, counts, issue types); locations and fix prompts stay in the owner-verified report. ## Threat briefs - [All threat briefs](https://shiplatch.com/threats) - [Exposed .env file](https://shiplatch.com/guides/check-if-env-is-exposed): Your secrets file can be downloaded from your live site. - [Supabase tables readable without RLS](https://shiplatch.com/guides/enable-supabase-rls): The anon key is public by design; Row Level Security is what keeps strangers out of your rows. - [Gemini API keys (AQ. auth keys) in client code](https://shiplatch.com/guides/google-api-keys-gemini): New Gemini keys start with AQ. and must never ship in your JavaScript. - [Vite dev server on a live site](https://shiplatch.com/threats/vite-dev-server): Running vite or npm run dev in production serves your source and, on older Vite versions, files like .env. ## Guides - [Is my Lovable app secure?](https://shiplatch.com/guides/is-my-lovable-app-secure): A practical checklist for Lovable apps on Supabase: leaked keys, RLS, .env exposure, and what a free passive scan can catch. - [How to enable Supabase Row Level Security (RLS)](https://shiplatch.com/guides/enable-supabase-rls): Step-by-step: turn on RLS, write auth.uid() policies, and verify strangers cannot read your tables. - [Exposed Supabase service_role key: what to do now](https://shiplatch.com/guides/exposed-supabase-service-role-key): If your service_role JWT is in the browser bundle, treat the database as compromised. Rotation and cleanup steps. - [Lovable security checklist](https://shiplatch.com/guides/lovable-security-checklist): Pre-launch security checklist for apps built with Lovable: secrets, auth, database rules, and headers. - [Bolt.new security checklist](https://shiplatch.com/guides/bolt-security-checklist): Pre-launch security checklist for apps built with Bolt.new: secrets, auth, database rules, and headers. - [Replit security checklist](https://shiplatch.com/guides/replit-security-checklist): Pre-launch security checklist for apps built with Replit: secrets, auth, database rules, and headers. - [Cursor security checklist](https://shiplatch.com/guides/cursor-security-checklist): Pre-launch security checklist for apps built with Cursor: secrets, auth, database rules, and headers. - [v0 security checklist](https://shiplatch.com/guides/v0-security-checklist): Pre-launch security checklist for apps built with v0: secrets, auth, database rules, and headers. - [Firebase rules open to the public: how to tell and how to fix](https://shiplatch.com/guides/firebase-rules-open-to-public): Spot open Realtime Database, Firestore, and Storage rules, and lock them down with auth-based rules. - [How to check if your .env is exposed](https://shiplatch.com/guides/check-if-env-is-exposed): One URL check that tells you if your production host is serving your secrets file — and how to fix it. - [How to hide API keys when an AI builder writes your app](https://shiplatch.com/guides/hide-api-keys-ai-builder): Patterns that keep OpenAI, Stripe, and other secrets out of the browser when you vibe-code. - [CVE-2025-48757 explained (Lovable + Supabase RLS)](https://shiplatch.com/guides/cve-2025-48757-lovable-rls): What the critical Lovable/Supabase RLS CVE was about, what the researcher found, and what to do on your app today. - [Supabase anon key explained: public by design, safe only with RLS](https://shiplatch.com/guides/supabase-anon-key-explained): Why seeing your anon key in the browser is normal — and when it becomes a breach. - [Security headers for vibe-coded apps](https://shiplatch.com/guides/security-headers-for-vibe-apps): The small set of HTTP headers worth setting on a Lovable, Bolt, or Replit deploy — and a prompt to add them. - [How to add security headers to a Lovable app](https://shiplatch.com/guides/security-headers-lovable-app): Lovable hosting sends HSTS, nosniff and Referrer-Policy but no CSP or clickjacking protection. Three ways to add them, and a CSP that won’t break your app. - [Fix it and prove it: a security workflow for vibe coders](https://shiplatch.com/guides/fix-it-and-prove-it-workflow): Scan, fix with AI prompts, re-scan, and only then ship — so the AI does not quietly undo your hardening. - [Leaked OpenAI API key: how to check and what to do](https://shiplatch.com/guides/leaked-openai-api-key): How to tell if your OpenAI key is exposed in your frontend or repo, how to revoke and replace it, and how to call OpenAI safely from a vibe-coded app. - [Is your Supabase Storage bucket public? How to check and lock it down](https://shiplatch.com/guides/supabase-storage-bucket-security): Public vs private Supabase Storage buckets, the storage.objects policies that control uploads and downloads, and signed URLs for private files. - [Security checklist before you launch a vibe-coded app](https://shiplatch.com/guides/pre-launch-security-checklist): A 15-minute pre-launch security pass for apps built with Lovable, Bolt, Replit, Cursor or v0: secrets, database rules, files, auth, headers and payments. - [Is it safe that my Firebase API key is public?](https://shiplatch.com/guides/firebase-api-key-public): The Firebase web apiKey is meant to be in your frontend. What actually protects your data: Security Rules, App Check, and key restrictions. - [Is my Bolt.new app secure?](https://shiplatch.com/guides/is-my-bolt-app-secure): The common security gaps in Bolt.new apps (keys in the bundle, Supabase RLS, exposed files) and how to check each one before launch. - [Leaked Stripe secret key (sk_live): what to do now](https://shiplatch.com/guides/leaked-stripe-secret-key): Your sk_live key ended up in a repo, bundle, or chat. The order of operations: roll it, check activity, fix the code. - [Hiding the admin button isn't access control: protect admin routes properly](https://shiplatch.com/guides/protect-admin-routes): In AI-built apps, admin pages are often protected only in the UI. How to enforce admin access where the data lives. - [Supabase RLS policy examples (user owns row, and why using(true) is not a fix)](https://shiplatch.com/guides/supabase-rls-policy-examples): Copy-paste Supabase Row Level Security policies for the most common vibe-coded app patterns, plus how to test them. - [Verify Stripe webhook signatures (Next.js, Supabase Edge Functions)](https://shiplatch.com/guides/verify-stripe-webhook-signature): Why an unsigned Stripe webhook lets anyone fake a payment, and how to verify the Stripe-Signature header correctly. - [Are VITE_ and NEXT_PUBLIC_ env variables public? Yes.](https://shiplatch.com/guides/vite-next-public-env-variables-are-public): Any env var prefixed VITE_, NEXT_PUBLIC_, or REACT_APP_ is compiled into your JavaScript bundle. What belongs there and what doesn't. - [Google API keys and Gemini: lock them down now](https://shiplatch.com/guides/google-api-keys-gemini): Gemini now rejects unrestricted Google API keys, but an AIza key whose restrictions include Gemini still works. How to restrict every key in about 10 minutes, and when to rotate. - [VITE_, NEXT_PUBLIC_, EXPO_PUBLIC_: the prefix means publish](https://shiplatch.com/guides/public-env-prefixes-vite-next-expo): Anything in a VITE_, NEXT_PUBLIC_, EXPO_PUBLIC_ or REACT_APP_ variable ships to every visitor. What is safe there, what is not, and how to move secrets server-side. - [Source maps in production: is your original code public?](https://shiplatch.com/guides/source-maps-in-production): Public source maps can expose your original code, including commented-out keys. How to check your site and turn them off in Vite, Next.js and CRA. - [Supabase is retiring anon and service_role keys: what to change](https://shiplatch.com/guides/supabase-anon-service-role-key-retirement): Supabase is replacing anon and service_role keys with sb_publishable_ and sb_secret_. What to change, which header to use, and what to rotate. - [Can I call the OpenAI API directly from my React app?](https://shiplatch.com/guides/call-openai-api-from-frontend): No, not with your own OpenAI key. Anything in your frontend bundle is readable by every visitor. Here's how to move the call to a server or edge function. - [I committed an API key to GitHub. What do I do?](https://shiplatch.com/guides/committed-api-key-to-github): Revoke or rotate the key first. Deleting the file or the commit doesn't make it safe, because the key stays in git history, clones and forks. Step-by-step from GitHub's own docs. - [Is it safe to put my ElevenLabs API key in the frontend?](https://shiplatch.com/guides/elevenlabs-api-key-in-frontend): No. ElevenLabs says never expose your API key in client-side code. Use a signed URL or a single-use token from your server instead. Steps and FAQ. - [How to test Supabase RLS (signed out, then as two users)](https://shiplatch.com/guides/test-supabase-rls): RLS being on doesn't prove your data is safe. Test it like a stranger: signed out, then as user A going after user B's rows. Copy-paste curl and SQL. - [Supabase Security Advisor warnings: which ones mean your data is open](https://shiplatch.com/guides/supabase-security-advisor): What each Supabase Security Advisor warning means for a vibe-coded app, which to fix first, and the AI fixes that quietly reopen your data.