Security check for Lovable apps
Paste the URL of your published app. We look at it the way any visitor can, explain each issue in plain English and give you a prompt Lovable can use to fix it.
First scan is free, no signup and no code access. By scanning you confirm you own this site or are authorized to test it, and agree to the Terms and Privacy Policy.

One key needs rotating before launch.
Built with Lovable · Supabase
Passive external check; application logic (SQLi, IDOR) is not tested.
Your app talks to Supabase straight from the browser. You click through it and everything loads, and nothing tells you that a stranger with the same public key could load your users’ rows too.
When a query failed during the build, the quickest way to make the error go away was a policy like using (true). The app works; the table is open.
An OpenAI or Stripe key pasted into a component ships to every visitor with your JavaScript, ready to copy.
01The bundlePublic
The browser downloads your JavaScript, and with it the Supabase URL, the anon key and the names of the tables the app reads. We read the same files.
/assets/index-3e9a.js
const supabase = createClient( "https://qzv.supabase.co", "eyJhbGciOiJIUzI1NiIs…" // role: anon);supabase.from("messages").select("*")
02The keysPublic
The anon key is meant to be public. A service_role key, or an OpenAI or Stripe key next to it, is not, and that is a critical finding.
Report
03The tablesVerified
After you verify the domain (free), we ask each table the bundle names for one row with that public key. We keep the status and column names, never the values.
Verified check
GET /rest/v1/messages?select=*&limit=1200 OK · 1 row[{ "id": "•••", "sender_email": "•••", "body": "•••"}]
Values hidden. We store the status and column names only.
04The fixPublic
Each finding comes with a prompt for the tool you build with. Paste it, publish, rescan.
Fix prompt for Lovable
The Supabase table "messages" can be read by anyone with the anon key. Enable Row Level Security on "messages" and add a select policy so a signed-in user only sees rows where sender_id = auth.uid(). Do not add any policy for the anon role.
Example data. Values in the table check are hidden.
The gaps Lovable apps ship with most often. Public checks run on every scan; Verified ones after you prove the domain is yours.
Whether the tables your app references answer without login, using the public anon key from your JavaScript. We ask for one row and never store it
After you verify
We decode every Supabase key in your bundle. The anon key is fine; a service_role key bypasses every policy and is a critical finding
Public
About 40 key patterns, such as OpenAI, Anthropic, Stripe and SendGrid, in the bundle and in published source maps
Public
Content-Security-Policy, HSTS and framing protection, plus SPF and DMARC so nobody can send email as you
Public
How it works
No code, no login, no setup. The first scan takes about a minute.
Each issue is explained by its consequence, in plain English, ranked by severity.
Copy the fix prompt for the issue and paste it into Lovable.
Verify your domain for free to unlock the deeper checks, then rescan to see the issue gone.
Free first scan. No signup, no code access.
A scan takes about a minute. Table and file checks run after free domain verification.
Inside the report
Every issue comes with a prompt written for the tool you build with. Paste it into Lovable, publish, and rescan to see the finding gone.
Lovable security guideCritical
profiles tableThe Supabase table answers without login, so the emails and phone numbers in it are public to anyone who opens your site.
GET /rest/v1/profiles?select=*&limit=1 with the anon key
In this Lovable project the Supabase table "profiles" can be read by anyone with the anon key. Write a migration that enables Row Level Security on "profiles" and adds policies so a signed-in user can select and update only the row where id = auth.uid(). Do not add any policy for the anon role.
Compared
| What | Shypset | Lovable’s built-in scan | Manual pentest |
|---|---|---|---|
| Where it looks | Your live site, from outside | Your project, from inside | Your app, by a security tester |
| Headers, TLS, DNS, email | Checked on every scan | Not covered | Usually covered |
| Works for any stack or host | Yes | Only apps built in Lovable | Yes |
| Logged-in logic (IDOR, per-user rules) | Not tested | Deeper inside the project | Yes |
| Cost and time | First scan free, about a minute | Free, inside the tool | Quoted per project, days to weeks |
Run the built-in scan too: it sees the inside. Shypset shows what a stranger sees.
Before / after
A service_role key skips every Row Level Security policy. If one reaches the browser, the fix is to keep it on the server and let the page use the anon key.
CriticalSupabase service_role key in the browserPublic check
export const supabase = createClient( SUPABASE_URL, "eyJhbGciOi…" // role: service_role);
Critical: the key bypasses every policy, and every visitor has it.
The Supabase client in the browser uses the service_role key. I have rotated it in Supabase. Switch the client to the anon key, move every action that needs elevated access into a Supabase Edge Function that reads the service role key from its environment, and check that Row Level Security is on for every table the app uses.
An example. Each finding in the report comes with a prompt like this.
Your first scan is free, no signup needed. Upgrade when you want the full report and fix prompts for every issue.
For your first check before launch
$0/ month
For founders shipping AI-built apps
$15/ month
Billed monthly, $180 a year
For agencies and freelancers. Coming soon
Soon
$9 one-time
One domain for 30 days: the full report and every fix prompt, plus 3 rescans. The public report and badge are not included.
Lovable’s scan looks at the project from the inside. Shypset looks at the published site from outside, the way a visitor or an attacker does, on any domain, including headers, TLS, DNS and email.
No. It is meant to be public. It is only safe when every table has Row Level Security, which is what the Verified table check tests.
The first scan is free, with no signup and no code access. A free account gives you 3 scans a month. The full report and a fix prompt for every issue come with Pro or a one-time $9 Launch Pass.
Without verification we only read what any visitor’s browser can, plus public records such as DNS. Deeper checks, like asking your database tables for a row, run only after you verify that the domain is yours. Verification is free.
No. It is a passive external check: it does not log in and does not test application logic such as SQL injection or IDOR. A clean report means nothing is visible from outside.
We check what it left open.Paste a URL and get the report in about a minute. First scan is free, no signup and no code access.
Real people read every message. Tell us what you need and we will answer by email.
Prefer email? Write to info@softdoes.com.