{"slug": "i-scanned-978-vibe-coded-apps-1-in-26-ships-a-secret-api-key-to-every-visitor", "title": "I scanned 978 vibe-coded apps. 1 in 26 ships a secret API key to every visitor.", "summary": "A developer built LeakLock, an open-source MIT-licensed scanner that inspects what a deployed site actually serves — HTML, JS bundles, lazy-loaded chunks and source maps — rather than the git repository. Scanning 978 public apps built with tools like Lovable, Bolt and v0, the developer found that roughly 1 in 26 ships a secret API key to every visitor, often via VITE_, NEXT_PUBLIC_ or REACT_APP_ environment variables baked into client bundles. The tool traces how a string is used — as an Authorization: Bearer header, an x-api-key header or a ?key= parameter — to identify credentials regardless of format, while marking intentionally public keys such as Supabase anon keys and Stripe pk_ keys as safe.", "body_md": "A few weeks ago I found an image-generation API key sitting in my own app's JavaScript bundle. Anyone who opened DevTools could copy it and bill me.\n\nThe confusing part: Gitleaks said my repo was clean. And it was. The key never touched git. It came in through a `VITE_` environment variable I'd set in my hosting dashboard, and the build baked it straight into the bundle.\n\nThat's the gap. Secret scanners check your repo. Nobody checks what your site actually serves.\n\nI collected 978 public apps built with tools like Lovable, Bolt and v0 (all linked from open GitHub repos) and scanned what each one sends to a browser: the HTML, the JS bundles, lazy-loaded chunks, and source maps.\n\nWhat came back:\n\nNo sites are named here, and keys were masked during the scan. The point isn't to shame anyone. Every one of these is an honest mistake that the tooling makes very easy.\n\n`VITE_`, `NEXT_PUBLIC_` or `REACT_APP_` goes into the client bundle. That's by design, but it's easy to forget when an AI assistant writes `import.meta.env.VITE_OPENAI_KEY` for you.\nRegex works for `sk-...` or `ghp_...`. It doesn't work for a random 40-character string that happens to be a key.\n\nSo instead of only matching shapes, I look at how the code *uses* a value. A string sent as `Authorization: Bearer`, in an `x-api-key` header, or as `?key=` in a request is almost certainly a credential, whatever it looks like. Trace the minified variable back to its literal, read the request host, and you can name the API too.\n\nThe opposite problem matters just as much. Supabase anon keys, Firebase web config and Stripe `pk_` keys are meant to be public. Flagging them is noise, so they're marked safe.\n\nI packaged this as **LeakLock**: open source, MIT, zero dependencies.\n\n```\nnpx github:sgroy10/leaklock scan https://your-site.com\n```\n\nOr in CI, scanning your deployed preview on every push:\n\n```\n- uses: sgroy10/leaklock@v1\n  with:\n    target: https://your-preview-url.com\n    fail-on: secret\n```\n\nRepo: [https://github.com/sgroy10/Leaklock](https://github.com/sgroy10/Leaklock)\n\nSpend two minutes on this:\n\n`key`, `token` and `secret`.\nWhat's the worst key you've found in a client bundle, yours or someone else's?", "url": "https://wpnews.pro/news/i-scanned-978-vibe-coded-apps-1-in-26-ships-a-secret-api-key-to-every-visitor", "canonical_source": "https://dev.to/sandeep_roy_c4e518c3f2641/i-scanned-978-vibe-coded-apps-1-in-26-ships-a-secret-api-key-to-every-visitor-2nj1", "published_at": "2026-10-23 11:31:55+00:00", "updated_at": "2026-10-23 11:41:12.345299+00:00", "lang": "en", "topics": ["ai-tools", "developer-tools", "ai-safety", "ai-agents"], "entities": ["LeakLock", "Lovable", "Bolt", "v0", "GitHub", "Supabase", "Firebase", "Stripe"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/i-scanned-978-vibe-coded-apps-1-in-26-ships-a-secret-api-key-to-every-visitor", "markdown": "https://wpnews.pro/news/i-scanned-978-vibe-coded-apps-1-in-26-ships-a-secret-api-key-to-every-visitor.md", "text": "https://wpnews.pro/news/i-scanned-978-vibe-coded-apps-1-in-26-ships-a-secret-api-key-to-every-visitor.txt", "jsonld": "https://wpnews.pro/news/i-scanned-978-vibe-coded-apps-1-in-26-ships-a-secret-api-key-to-every-visitor.jsonld"}}