Check your Supabase project against 45 OWASP Top 10:2025 rules and more
Connect one project read-only and get a graded report with the fix for each finding, right on this page.
For teams shipping with Lovable, Bolt, Cursor or v0 on Supabase. Free, no sign-up.
Free, no signup. Read-only: nothing in your project is changed.
- Connect SupabaseApprove read-only access on supabase.com.
- We run 45 checksAccess and RLS, sign-in, storage and functions, infrastructure. Catalog and settings only, never your rows.
- Report and a prompt for your AI agentA fix for each finding plus a prompt you paste into Cursor, Claude Code or Lovable. Stored only if you share it.
Loading your Supabase projects…
Choose a project to scan
20 lowercase letters, as in supabase.com/dashboard/project/your-ref.
Confirm you are human
This keeps automated scans off the service.
Scan log
What the check can see
We read
- Database catalog: tables, RLS flags, policies, grants, views, functions, extensions, roles and who may read the Vault
- Auth settings: password rules, email confirmation, MFA, redirect URLs
- Storage: the bucket list, which buckets are public and their size and file-type limits
- Edge Functions: the list and the JWT setting of each one
- Project settings: Postgres version, backups, SSL, network restrictions, Data API row cap
We never read
- Rows in your tables
- API keys and secrets: Supabase includes a few in settings replies, and the scan drops them on arrival without storing, logging or showing them
- Files stored in your buckets
- Your app code and repository
A report is stored only when you create a share link, for 7 days at most. The access grant is revoked right after the check.
What read access cannot check
- A06 Insecure Design and A10 Mishandling of Exceptional Conditions live in your app code, not in project settings.
- Frontend dependencies (the npm part of A03) and a service_role key bundled into frontend code. Check your repository for those.
- Access rules that live only in app code or Edge Functions, such as a plan = 'pro' check in the frontend. The scan sees only columns the database itself uses in policies, functions and auth hooks, so a pass on writable access columns does not mean those columns are safe.
- Whether one signed-in user can read another user’s rows. That needs a test with two real users: how to test Supabase RLS
Supabase Security Advisor and this check
| Question | Security Advisor | This check |
|---|---|---|
| Where it runs | In the Supabase dashboard, one project at a time | On this page, after read-only OAuth, for the project you pick |
| What it reads | Database lints | The same lints as one check, plus auth, storage, Edge Functions, backups and network settings |
| How results are grouped | By lint | By OWASP Top 10:2025, with the categories it cannot check named |
| What you get to fix it | A link to the lint documentation | SQL or the dashboard setting per finding, and a prompt for your AI agent |
| What you can keep | The list in your dashboard | A PDF, or a share link that expires after 7 days |
OWASP Top 10:2025 coverage
| Category | Checks | Status |
|---|---|---|
| A01 Broken Access Control | 18 | Covered |
| A02 Security Misconfiguration | 9 | Covered |
| A03 Software Supply Chain Failures | 2 | Partly Postgres version and extensions only. npm dependencies live in your repository. |
| A04 Cryptographic Failures | 4 | Covered |
| A05 Injection | 1 | Covered |
| A06 Insecure Design | 0 | Not checkable Insecure design lives in how your app works, not in settings. |
| A07 Authentication Failures | 8 | Covered |
| A08 Software or Data Integrity Failures | 1 | Covered |
| A09 Security Logging and Alerting Failures | 2 | Covered |
| A10 Mishandling of Exceptional Conditions | 0 | Not checkable Error handling lives in your app code, which read access never sees. |
All 45 checks
| Check | ID | OWASP | Worst case |
|---|---|---|---|
| RLS disabled on exposed tables | rls_disabled_exposed | A01 | Critical |
| Policies that allow every row | policy_always_true | A01 | High |
| Policies that trust user metadata | policy_uses_user_metadata | A01 | High |
| Write policies open to anonymous visitors | anon_write_policies | A01 | High |
| Views that bypass RLS | views_without_security_invoker | A01 | High |
| Materialized views or foreign tables in the API | matviews_or_foreign_tables_exposed | A01 | Medium |
| Security definer functions callable from the API | security_definer_executable | A01 | High |
| Storage policies open to anonymous visitors | storage_objects_anon_policies | A01 | High |
| Public storage buckets | public_buckets | A01 | Low |
| Realtime private channels without protection | realtime_messages_rls | A01 | High |
| Unused write grants for anonymous visitors | anon_table_grants_write | A01 | Low |
| Roles that bypass RLS | roles_bypass_rls | A01 | High |
| Access columns signed-in users can change | authz_columns_writable | A01 | High |
| Delete and re-insert changes a protected column | delete_insert_bypass | A01 | High |
| Unneeded table privileges for signed-in users | authenticated_table_grants_extra | A01 | Low |
| Default privileges that open new objects to the API | default_privileges_api_roles | A01 | Low |
| Security definer functions that check current_user | definer_checks_current_user | A01 | Medium |
| Policies without a role or a command | policies_without_to_or_for | A01 | Low |
| Supabase Security Advisor findings | advisor_lints | A02 | High |
| Extra schemas exposed in the Data API | extra_exposed_schemas | A02 | High |
| Wildcards in redirect URLs | redirect_wildcards | A02 | Medium |
| Redirect URLs over http or to localhost | insecure_redirect_urls | A02 | Medium |
| Anonymous sign-ins on | anonymous_signins_enabled | A02 | Medium |
| CAPTCHA off for sign-up and sign-in | captcha_disabled | A02 | Medium |
| Database open to every IP address | network_open | A02 | Medium |
| Public buckets without upload limits | public_bucket_no_limits | A02 | Low |
| No row cap on Data API responses | postgrest_max_rows | A02 | Medium |
| Postgres upgrade available | postgres_upgrade_available | A03 | Medium |
| Installed extensions | extensions_listed | A03 | Info |
| SSL not enforced on database connections | ssl_enforcement_off | A04 | Medium |
| Access tokens valid longer than an hour | jwt_expiry_long | A04 | Medium |
| Sensitive-looking columns readable by anonymous visitors | sensitive_columns_exposed | A04 | High |
| Vault secrets readable by API roles | vault_secrets_exposed | A04 | Critical |
| Dynamic SQL built from strings | dynamic_sql_concat | A05 | Medium |
| Short minimum password length | password_min_length | A07 | High |
| Leaked password protection off | leaked_password_protection_off | A07 | Medium |
| Email confirmation off | email_confirm_off | A07 | High |
| Secure email change off | secure_email_change_off | A07 | Medium |
| One-time codes valid longer than an hour | otp_expiry_long | A07 | Medium |
| No multi-factor method enabled | mfa_unavailable | A07 | Medium |
| Refresh token rotation off | refresh_token_rotation_off | A07 | Medium |
| Password change without reauthentication | password_change_no_reauth | A07 | Low |
| Edge Functions without JWT verification | edge_functions_without_jwt | A08 | Low |
| pgaudit not installed | pgaudit_missing | A09 | Info |
| No backups found | backups_or_pitr | A09 | Medium |
Questions
How is this different from the Supabase Security Advisor?
The Security Advisor results are one of the checks. The scan adds auth settings, storage policies, Edge Functions, backups and network settings, groups everything by OWASP Top 10:2025 and gives a fix for each finding.
Is Supabase secure by default?
The platform is maintained by Supabase, but the access rules are yours. A new table created with plain SQL has Row Level Security off, and a policy written as using (true) lets anyone with the anon key read the table. The scan looks for exactly these settings.
What does “RLS disabled” mean, and how do I enable it?
With RLS disabled on a table in an exposed schema, anyone with your anon key can read every row through the Data API. Enable it with alter table public.your_table enable row level security; then add policies for the access you want.
Is it safe that my Supabase anon key is in the browser?
Yes, the anon (publishable) key is meant to be public. It can do only what your grants and RLS policies allow, which is why the scan checks those. The service_role key bypasses RLS and must never reach the browser.
Check your own project
Free and read-only. The report appears on this page.
Check my Supabase project