Postgres Views: The Hidden Security Gotcha in Supabase

When building with Supabase, Postgres Views can be a powerful tool for simplifying complex queries. But they come with a critical security consideration that isn't immediately obvious: Views bypass Row Level Security (RLS) by default, potentially exposing sensitive data even when your tables are properly secured. As a reminder: RLS is what allows you to safely query your Supabase database directly from the frontend, without routing through your backend server. But if RLS isn't working on a table, that table is like your phone screen on public transport—anyone who wants to take a glance, can. The Security Challenge Even if you've carefully configured RLS policies on your tables, views can create an unintended backdoor because: By default, views don’t use RLS Supabase's RLS policies page doesn't show or warn about exposed views (last checked 09.03.2025) Views don't support RLS in the same way tables do Testing Your View's Security Before deploying any view to production, it's crucial to verify that it properly respects your RLS policies. Here's a quick way to test if your view is secure: // First, sign in as a specific user // Then try to fetch ALL rows from your view const { data } = await supabase.from('my_view').select('*') // If your view respects RLS, you should only see rows this user has permission to access. // If you see ALL rows, your view is bypassing RLS!

Mar 9, 2025 - 22:52
 0
Postgres Views: The Hidden Security Gotcha in Supabase

When building with Supabase, Postgres Views can be a powerful tool for simplifying complex queries. But they come with a critical security consideration that isn't immediately obvious: Views bypass Row Level Security (RLS) by default, potentially exposing sensitive data even when your tables are properly secured.

As a reminder: RLS is what allows you to safely query your Supabase database directly from the frontend, without routing through your backend server. But if RLS isn't working on a table, that table is like your phone screen on public transport—anyone who wants to take a glance, can.

The Security Challenge

Even if you've carefully configured RLS policies on your tables, views can create an unintended backdoor because:

  • By default, views don’t use RLS
  • Supabase's RLS policies page doesn't show or warn about exposed views (last checked 09.03.2025)
  • Views don't support RLS in the same way tables do

Testing Your View's Security

Before deploying any view to production, it's crucial to verify that it properly respects your RLS policies. Here's a quick way to test if your view is secure:

// First, sign in as a specific user
// Then try to fetch ALL rows from your view
const { data } = await supabase.from('my_view').select('*')
// If your view respects RLS, you should only see rows this user has permission to access.
// If you see ALL rows, your view is bypassing RLS!