Security Bug: Realtime Subscription Leaks Draft and Soft-Deleted Model Data
Description
The client-side Supabase Realtime subscription listens for all
postgres_changes on the models table without a row-level filter predicate.
Every connected browser receives the full payload of every INSERT, UPDATE, and
DELETE event, including rows in draft status or marked as soft-deleted
(e.g., status = 'draft' or deleted_at IS NOT NULL). Unpublished model
entries with pricing, benchmark data, or API keys submitted by contributors
awaiting review are broadcast to all connected clients.
Steps to Reproduce
- Open the AIAtlas dashboard in a browser and subscribe to Realtime updates.
- In another session (admin), create a draft model entry.
- Observe the Realtime event arrives in the first browser's subscription
with the full draft record, including any unpublished fields.
Root Cause
The Supabase channel().on('postgres_changes', ...) subscription is called
without a filter argument, which causes Supabase to send all changes.
Impact
Pending/draft model submissions (which may contain proprietorial pricing data
or early-access API keys) are broadcast to all connected users before review.
Proposed Fix
Add a filter to receive only published, non-deleted records:
supabase
.channel("public:ai_models")
.on(
"postgres_changes",
{
event: "*",
schema: "public",
table: "ai_models",
filter: "status=eq.published", // Only published entries
},
(payload) => handleModelUpdate(payload)
)
.subscribe();
Security Bug: Realtime Subscription Leaks Draft and Soft-Deleted Model Data
Description
The client-side Supabase Realtime subscription listens for all
postgres_changeson the models table without a row-level filter predicate.Every connected browser receives the full payload of every INSERT, UPDATE, and
DELETE event, including rows in draft status or marked as soft-deleted
(e.g.,
status = 'draft'ordeleted_at IS NOT NULL). Unpublished modelentries with pricing, benchmark data, or API keys submitted by contributors
awaiting review are broadcast to all connected clients.
Steps to Reproduce
with the full draft record, including any unpublished fields.
Root Cause
The Supabase
channel().on('postgres_changes', ...)subscription is calledwithout a
filterargument, which causes Supabase to send all changes.Impact
Pending/draft model submissions (which may contain proprietorial pricing data
or early-access API keys) are broadcast to all connected users before review.
Proposed Fix
Add a filter to receive only published, non-deleted records: