Is My Web App Secure Enough to Go Live?
You're staring at the deploy button. Somewhere in the back of your mind is a voice asking "is this actually safe?" Here's a concrete, pass/fail way to answer that — no security background required.
The Question Every Founder Asks Before Shipping
You built the thing. Cursor, Lovable, or Bolt got you from idea to working app faster than ever. But somewhere between "it works on my machine" and "real strangers are about to use this," a specific anxiety kicks in: what if it's not actually safe?
That question is usually too vague to answer. "Secure" isn't a single thing you can verify — it's a bundle of specific, checkable facts about your app. This is the checklist that turns the vague fear into five concrete pass/fail checks you can run in the next ten minutes.
Check 1: Authentication Actually Blocks Unauthenticated Requests
Having a login page is not the same as having authentication. The test: open an incognito window (no session), and try to hit a route that should require login directly by URL — a dashboard page, an API endpoint like /api/user/profile, an admin panel.
Pass: every protected route returns a redirect or a 401/403 with no data.
Fail: you see real data, or the page renders before redirecting (data already left the server).
This is the single most common gap in AI-generated apps — the frontend hides the link, but the backend route never checks who's asking.
Check 2: No API Keys or Secrets in Your JS Bundle
Open your deployed site, view source, and search the loaded JavaScript for anything that looks like a key: sk-, AKIA, service_role, or any environment variable name containing SECRET or KEY. Browser dev tools → Sources tab → search across files works well for this.
Pass: nothing matches. Server-only keys never leave the server.
Fail: you find a live key. Anything prefixed NEXT_PUBLIC_ (or your framework's equivalent) ships to every visitor's browser — it is public by definition, so it must never hold a secret.
A leaked OpenAI or Supabase service-role key gets scraped by bots within minutes of a page loading — this isn't a theoretical risk.
Check 3: Standard Security Headers Are Present
Open your browser's Network tab, reload the page, click the main document request, and look at the Response Headers.
Pass: you see Strict-Transport-Security, Content-Security-Policy, X-Frame-Options (or frame-ancestors in CSP), and X-Content-Type-Options: nosniff.
Fail: none of these appear. Most frameworks don't set them by default — you have to add them explicitly.
These headers are cheap to add and close off entire attack classes: clickjacking, MIME-sniffing attacks, and protocol-downgrade attacks on your traffic.
Check 4: Database Row-Level Security Is Enabled and Correct
If you're on Supabase (or any Postgres backend with row-level security), this is the check that matters most and is hardest to self-verify from the outside. The test: create two test accounts, log in as account A, and try to fetch a record that belongs to account B — either through the app UI or by calling the API directly with account A's session.
Pass: account A gets an empty result or a permission error — never account B's data.
Fail: account A can read (or worse, write) account B's row. This means RLS is either disabled or the policy logic has a gap.
A large share of AI-built Supabase apps ship with RLS disabled entirely, because it's off by default on new tables and the app still "works" in testing — until a second user shows up.
Check 5: HTTPS Is Enforced, No Mixed Content
Type your domain into the address bar with http:// instead of https:// and load it. Then check the padlock icon on the real page for any "not fully secure" warnings.
Pass: the http version redirects to https automatically, and the padlock shows no warnings.
Fail: the http version loads without redirecting, or you see a mixed-content warning (some resources loading over plain http on an https page).
Scoring Yourself
Five checks, five pass/fails. This isn't a certification — it's a floor. Passing all five doesn't mean your app is unhackable; it means you've closed off the handful of mistakes that account for the overwhelming majority of real-world breaches in AI-generated apps: exposed secrets, open databases, and routes nobody remembered to protect.
- 5/5 — you've covered the baseline. Ship it, then keep monitoring.
- 3–4/5 — fixable in an afternoon. Don't launch until the failures are closed, especially RLS or exposed secrets.
- 0–2/5 — stop and fix before any real user touches this. These are the exact patterns that make the news.
Doing It the Slow Way vs. the Automated Way
Everything above can be done manually with a browser and ten minutes. The RLS check is the one place manual testing gets awkward — it needs two accounts, careful comparison, and repeating for every table you have, and you have to redo the whole thing every time you ship a change.
Vezraa automates all five checks (plus about 85 more) from a single URL — no login, no repo access, no second test account to manage. It actively tests your live RLS policies, greps your deployed bundle for real key patterns, checks your header configuration, and confirms HTTPS enforcement, then hands you a scored report with the exact fix for anything that fails. Most scans finish in about 25 seconds.
Skip the manual checklist — scan your live app in 25 seconds.
Scan Your App →