The risk is running the wrong check and calling it done
The concrete launch risk in a public scan vs code review security decision is simple: you run one of the two, it comes back clean, and you ship believing you are covered for a class of problem the check you ran was never designed to see. A clean public scan tells you nothing about whether a logged-in user can read another user's invoices. A careful code review of your authorization logic tells you nothing about whether your production build is serving source maps or an exposed .env to anyone who requests it.
These are two different lenses, not two strengths of the same tool. A public-surface scan looks at your app from the outside, as an anonymous visitor or crawler would, and reports what is observably reachable right now on the deployed URL. A code review looks at the source from the inside and reasons about what the code is allowed to do across all the paths a scan never walks.
The failure is not that either check is weak. It is treating one as a substitute for the other, then mistaking a passing result for full coverage.
- A scan proves what is exposed on the live surface today. It cannot reason about intent.
- A review proves what the code permits across roles and edge cases. It cannot see what the running deploy actually serves.
- "It passed" is only meaningful once you know which question it answered.
Why AI-built apps land on the wrong side of this
AI-built apps reach a working, deployed URL fast, and that speed is exactly what collapses the two checks into one in a builder's head. The app loads, the happy path works, the public URL is live before anyone has separated "looks finished" from "was reviewed."
Two generated defaults make this worse. First, build tooling often ships source maps and verbose artifacts unless told not to, so the deployed surface carries more than the developer realizes, and that is squarely scan territory. Second, generated authorization is frequently shallow. A prompt that says "let users edit their profile" produces a working edit form, but whether the server actually checks that the caller owns the profile they are editing is an Access Control concern (OWASP A01, Broken Access Control) that only a code review or a deliberate authorization test can confirm. The form working in your own session does not exercise that check.
So the builder runs whichever check is closer to hand, gets a green result, and generalizes it. A clean scan feels like "secure." A reviewed data model feels like "shipped safely." Neither is the whole picture.
- Fast deploy means the public surface exists before any review loop runs.
- Generated code makes the happy path work, which hides untested authorization branches.
- One green check gets mentally promoted to full coverage.
What each check actually proves
Here is the side-by-side, framed as what is observable from outside versus what requires reading the code. Treat it as a scope map, not a ranking.
A public-surface scan can prove things that are reachable on the deployed URL without credentials:
A code review (or a manual authorization test) can prove things a scan structurally cannot:
The dividing line is the credential and the logic boundary. A scan sees the unauthenticated, observable surface. A review sees the authenticated paths and the reasoning behind them. Neither sees the other's domain.
- Missing or weak security response headers, for example absent Strict-Transport-Security, Content-Security-Policy, or X-Content-Type-Options.
- Source maps served in production, which hand readers your original source.
- Exposed build and deploy artifacts: a readable .env, a reachable .git/HEAD, backup files left in the web root.
- Secret-shaped strings in the client bundle, for example a token that looks like sk_live_ or sk-ant- or a service_role JWT that should never ship to a browser.
- Publicly readable buckets or endpoints, and open or wildcard CORS such as Access-Control-Allow-Origin: *.
- Whether the server enforces that the caller owns the record they are reading or writing. This is authorization, distinct from authentication: a valid login proves who you are, not what you are allowed to touch.
- Business rules: can someone set a negative quantity, skip a payment step, or call an admin-only handler.
- Data flow: where untrusted input reaches a query or a template, and whether it is parameterized or escaped.
- Multi-tenant isolation: whether one account's data can leak into another's response.
Run the scan first as the fast pass, then review the logic
These checks compose; they do not compete. Run the cheap, broad, outside-in pass first, fix anything it surfaces, then spend your slower manual attention on the logic a scan can never reach. You can reproduce the public side on your own app right now.
What this sequence does not cover is everything on the review side. Fixing every scan finding does not check a single authorization rule. So after the scan is clean, log in as one test user and try to read or edit a second user's record by its id. If the server returns it, you have a Broken Access Control finding no scan would ever have reported.
- Open your deployed app, open DevTools, and watch the Network tab. Look for .js.map files loading in production. The safer result is no source maps; the suspicious result is your original source reconstructable in the Sources panel.
- Request a few artifact paths against your own URL: GET /.env, GET /.git/HEAD, GET /config.json. The safer result is a 404 or a 403. The suspicious result is real content coming back.
- Read the response headers on your main document. The suspicious result is a missing Content-Security-Policy or an Access-Control-Allow-Origin: * where it should be scoped. The safer result is headers present and CORS limited to origins you control.
- Search your built client bundle for secret prefixes such as sk_live_, sk-ant-, or service_role. The safer result is only publishable or anon keys present. The suspicious result is any secret-class string in code a browser downloads.
A scan finding is reproducible and observable: you requested a URL and got back something that should not be public. An authorization gap is usually only "possible" until you deliberately test the specific path. Do not let a clean scan stand in for the authorization test you have not run.
Where VibeCodeGuard fits, and what it does not prove
VibeCodeGuard is the public-scan side of this comparison, and it is positioned honestly as the fast first pass, not a code-review replacement. Its Launch Check looks at your deployed URL from the outside and reports the observable surface: security headers, source maps, exposed build and deploy artifacts, secret-shaped strings in the client bundle, publicly readable endpoints, and open or wildcard CORS, each with a severity rating and fix direction. That is the cheap, repeatable pass you run before you share the URL, and the right place to start because it catches the exposures that are live the moment you deploy. When findings come back, deciding what to fix first is its own skill, covered in how to read a security scan result and triage findings.
What it does not do is read your code. It does not confirm that authorization is enforced, that business rules hold, or that one tenant's data cannot reach another's response. Those need a code review or a deliberate manual test, and at a certain threshold a real engagement: when you handle regulated data, payment flows, or multi-tenant isolation, the question shifts to whether you need a penetration test, which is a different thing again.
Next step: run a focused Launch Check against your public URL before sharing it, fix anything it flags, then sit down and manually test one authorization path you have never deliberately checked. The two together cover far more than either alone.
A clean Launch Check proves the observable public surface is clean today. It does not prove your authorization logic is correct, because a scanner cannot see code it is not allowed to read. Treat the scan as the fast first pass and the authorization review as a separate, required step.
> launch check
Scan the public surface before launch.
Get severity, evidence, and practical fix guidance for the checks VibeCodeGuard can run from the outside.