v0 security scanner
v0 generates a React or Next.js app and deploys it to Vercel, often with Supabase or a hosted Postgres for data. The build is fast and clean, but the security settings are not part of what it generates. This page explains what to check and scans your live app now.
Scan your v0 app
What it means
Anyone can read this table without logging in. That can be deliberate, such as reference data or a public directory, or a missing access policy; only you can say which. xlogs read one row's column names and kept none of its values.
Why AI tools cause it
Supabase only limits who can read a table once you turn on Row Level Security (RLS) and write access rules for it. An AI tool can build a working app without doing that, and a table without RLS, or with a policy that lets everyone read, answers anonymous requests.
How xlogs checks it
xlogs finds your public Supabase URL and anon key in your app (the same ones your frontend uses), asks the database for its table list, reads one row from each listed table as an anonymous user, and flags any that return rows. Hosted Supabase refuses that list to public keys, so on a hosted project the result says the tables could not be checked. Read-only: it never writes or deletes.
What to check first on a v0 app
Two things to check first on a v0 app. If the app uses Supabase, whether its tables can be read by anyone, which happens when Row Level Security was never turned on. And whether source maps ship to production: Next.js does not ship them by default, but a project configured to emit them can, and a map with your source text lets anyone read your original code.
Neither shows up while you use the app. The scan below checks the deployed app for both, plus exposed keys and missing headers.
The top v0 security issues to check
- Publicly readable Supabase database (Row Level Security off)
- Source maps that expose your original source code
- An API key or service key exposed in the client bundle
- Missing security headers (CSP, HSTS, X-Frame-Options)
How to fix it
The goal: Row Level Security is enabled on every table, and each table returns rows only to the users it is meant for: a private table answers no anonymous request, and a table that is public on purpose has a read policy that says so.
- Decide whether the affected spot is meant to be readable without a login
- If it is not, enable Row Level Security (RLS) on the affected spot and add a policy so only the users allowed to see a row can read it
- If it is, keep it public on purpose, and record that decision so a review does not reopen it
- Do not switch on a restrictive policy for a table your public pages read without a replacement read policy, or those pages stop working
- Re-check that an anonymous request returns what you decided it should
In my app (the spot the scan shows): anyone can read this table; confirm that is deliberate. Please make this true: Row Level Security is enabled on every table, and each table returns rows only to the users it is meant for: a private table answers no anonymous request, and a table that is public on purpose has a read policy that says so. Steps: Decide whether the spot the scan shows is meant to be readable without a login; If it is not, enable Row Level Security (RLS) on the spot the scan shows and add a policy so only the users allowed to see a row can read it; If it is, keep it public on purpose, and record that decision so a review does not reopen it; Do not switch on a restrictive policy for a table your public pages read without a replacement read policy, or those pages stop working; Re-check that an anonymous request returns what you decided it should. Then tell me exactly what you changed, and do not print any secret values back to me or write one into a commit message, a pull request description or a log.
Then verify: After you decide and deploy, xlogs repeats the same anonymous read of each table the database lists and reports what comes back: a table you made private should no longer return rows, and one you keep public still will. If the table list is refused, it says the tables could not be checked.
Full step-by-step fix guide, with a copy-paste block for each AI tool →
Common questions
Does v0 handle security for me?
No. v0 generates the app and Vercel hosts it, but database access rules and a Content-Security-Policy are yours to set, and whether source maps or other headers ship depends on your configuration. The scan shows what your deployment actually serves.
Why would my v0 app leak its source code?
Build tools generate source maps to help with debugging, and it is easy to ship them to production by accident. When they are public, anyone can reconstruct your original, unminified code (and any secrets in it) straight from the browser. The scan checks for this.
