Database Migrations Not in Repository
Database schema changes are applied manually through the Supabase Dashboard instead of tracked migration files, making security audits and rollbacks impossible.
How It Works
When developers modify the database schema directly through the Supabase Dashboard SQL editor instead of using migration files, changes are untracked and unreviewable. There is no history of what was changed, when, or by whom. RLS policies, function definitions, and table structures can be silently modified without code review. This makes it impossible to audit security configurations, reproduce the database in a new environment, or roll back dangerous changes. It also prevents CI from validating that RLS is properly configured.
# Project structure missing migrations
my-app/
src/
package.json
# No supabase/ directory!
# Schema changes done manually in Dashboard# Proper Supabase project structure
my-app/
src/
package.json
supabase/
migrations/
20240101000000_create_profiles.sql
20240102000000_add_rls_policies.sql
20240103000000_create_storage_policies.sql
seed.sql
config.tomlReal-World Example
A fintech startup had no migration files and made all schema changes through the Dashboard. When a developer accidentally dropped an RLS policy in production, there was no record of the original policy, no way to roll back, and the table was exposed for 3 hours before anyone noticed.
How to Prevent It
- Use supabase db diff to generate migration files from Dashboard changes
- Store all migrations in the repository under supabase/migrations/
- Require code review for all migration files before applying them
- Set up CI to run supabase db lint on every pull request
Affected Technologies
Data Hogo detects this vulnerability automatically.
Scan Your Repo FreeRelated Vulnerabilities
Row Level Security Disabled
criticalSupabase tables without RLS enabled allow any authenticated or anonymous user to read, insert, update, and delete all rows using the client library.
RLS Policy with USING(true)
criticalRLS policies that use USING(true) or WITH CHECK(true) effectively disable row-level security by allowing all operations for all users.
RLS Enabled Without Policies
highRLS is enabled on a table but no policies are defined, which silently blocks all access including legitimate queries from your application.
Service Role Key Exposed
criticalThe Supabase service_role key is hardcoded in frontend code, committed to a repository, or exposed in client bundles, granting full database admin access to anyone.