We found 4 findings
Your app hands every visitor a key with Stripe's live prefix. And 3 more things to look at.
- 3 checks
- 37 requests
- 0 writes kept
- 2 seconds
- 5 November 2026 at 3:27 am UTC
- 2 not checked
We couldn’t run 2 tests from outside. Add this app and connect your database to run them.
4 findings, worst first
What a stranger or your users can reach.
Add this app to get a fix for each finding and to track which ones you’ve fixed.
CriticalYour app hands every visitor a key with Stripe's live prefix.It starts with the prefix Stripe gives a live secret key. We did not try it. It is in page-042961aeec436551.js, which a browser fetches in the open.
Proof
We asked for the JavaScript your app serves to anyone who opens it.
The same download
also handed us your app's own public key
Your app's JavaScript, as a visitor downloads it
carries a key 42 characters long
Your app's JavaScript carries a key 42 characters long; the same download also handed us your app's own public key. Same minute.
where we found it, and what was seen of it
- Where
- https://demo-app.example/_next/static/chunks/app/orders/page-042961aeec436551.js?dpl=dpl_DYtH2DLxLSQwMsRCSkSizy1NJF2P
- What was seen of it
- sk_liv…0000
How to fix it
- A fix drafted for this finding, ready to paste into Supabase
- The same fix as a prompt for your AI builder
- Verify fix, which tests the finding again and marks it verified when the fix holds
Add this app to get a fix for each finding and to track which ones you’ve fixed.
CriticalYour app hands every visitor a key that bypasses every rule you have set.Anyone who opens your site can read, change or delete any of your data with it. It is in page-042961aeec436551.js, which a browser fetches in the open.
Proof
We asked for the JavaScript your app serves to anyone who opens it.
The same download
also handed us your app's own public key
Your app's JavaScript, as a visitor downloads it
carries a key 228 characters long
Your app's JavaScript carries a key 228 characters long; the same download also handed us your app's own public key. Same minute.
where we found it, and what was seen of it
- Where
- https://demo-app.example/_next/static/chunks/app/orders/page-042961aeec436551.js?dpl=dpl_DYtH2DLxLSQwMsRCSkSizy1NJF2P
- What was seen of it
- eyJhbG…TElE
- What it claims to be
- role service_role, project demo-project
How to fix it
- A fix drafted for this finding, ready to paste into Supabase
- The same fix as a prompt for your AI builder
- Verify fix, which tests the finding again and marks it verified when the fix holds
Add this app to get a fix for each finding and to track which ones you’ve fixed.
HighAnyone can list the files in avatars.1 file was named to a request anyone can make, and a file's name usually says what is in it.
Proof
We asked for a listing of the files in avatars, over your app's public web address.
The same listing, for a file store with nothing behind it
answered, and we read what came back
A stranger, with the key your app ships to every visitor
listed 1 file
A stranger listed 1 file; the same listing for a file store with nothing behind it answered, and we read what came back. Same minute, same key.
the request and both answers
- What we asked
- POST https://demo-project.example/storage/v1/object/list/avatars
- Headers we sent
- apikey, authorization
- What came back
- 200
- What we asked for the control
- POST https://demo-project.example/storage/v1/object/list/witness_control_52aebd28
- What the control got back
- 200
- Fields a stranger could see
- name (string), version (null), id (null), updated_at (null), created_at (null), last_accessed_at (null), metadata (null), archived_at (null), is_delete_marker (null), is_versioned (null)
Run both, and compare
View · 11 lines
# What a stranger asked, and got: curl -s -i -X POST \ -H 'apikey: <your app's public key>' \ -H 'authorization: Bearer <your app's public key>' \ 'https://demo-project.example/storage/v1/object/list/avatars' # And the same listing for a file store with nothing behind it, for comparison: curl -s -i -X POST \ -H 'apikey: <your app's public key>' \ -H 'authorization: Bearer <your app's public key>' \ 'https://demo-project.example/storage/v1/object/list/witness_control_52aebd28'How to fix it
- A fix drafted for this finding, ready to paste into Supabase
- The same fix as a prompt for your AI builder
- Verify fix, which tests the finding again and marks it verified when the fix holds
Add this app to get a fix for each finding and to track which ones you’ve fixed.
HighAnyone can sign up as anyone.An email address is never proven, so someone can register with a customer's address and be treated as that customer.
Proof
We asked for your app's own sign-up settings, which anyone may read.
The same read of the project's own sign-in settings
answered, and we read it
Your app's own sign-up settings
say mailer_autoconfirm is true
Your sign-up settings say mailer_autoconfirm is true; the same read of your own sign-in settings answered, and we read it. Same minute, same key.
the setting we read, and where
- Where
- https://demo-project.example/auth/v1/settings
- Setting
- mailer_autoconfirm = true
How to fix it
- A fix drafted for this finding, ready to paste into Supabase
- The same fix as a prompt for your AI builder
- Verify fix, which tests the finding again and marks it verified when the fix holds
Add this app to get a fix for each finding and to track which ones you’ve fixed.
How the check went
The four steps of every check, and what each one found.
Reading your app’s code, done
The code your app ships: Found something.
Testing as a stranger, done
Your data API, from outside: Found something. Signing up and signing in: Found something.
Testing as your users, not checked
Not checked. Add this app and connect your database to run it.
Writing your report, done
Done in 2 seconds. Nothing in your app changed.
Show everything we checked, line by line
| Area | Status | Result |
|---|---|---|
| The code your app ships | Found something | 16 of 16 script files read, 1 check found something to look at, below. |
| Your data API, from outside | Found something | 1 check found something to look at, below. |
| Signing up and signing in | Found something | 1 check found something to look at, below. |
- Your app's pages
- 8 pages loaded: /, /orders, /signin, /why, /profile, /settings, /checkout, /signup
- The code it ships
- 16 of 16 script files the pages named
- Tables
- 4 tables: orders, invoices, profiles, notes
- File stores
- 1 file store: avatars
- Sign-up settings
- read, as anyone may
- What we sent
- 37 requests, at most 4 requests at a time, and nothing that changes anything
- Your app's code, and the files it ships
- something to look at, below
- What a stranger could reach
- something to look at, below
- Your sign-up and email settings
- something to look at, below
Not checked
What this check couldn’t test, and what would let it.
Needs a deeper check
This needs a deeper check than this run had.
Connect the level it names; the card on the Connect page says exactly what that takes.
Show why
Whether the 1 table that answered a stranger with no rows is empty or hidden by a rule needs the Inside check. Two statements on screen unlock it, each adding one limited database login.