supabase / walrus

Applying RLS to PostgreSQL WAL
Apache License 2.0
122 stars 9 forks source link

dynamic table name in subscription permissions check #44

Closed olirice closed 2 years ago

olirice commented 2 years ago

What kind of change does this PR introduce?

https://github.com/supabase/walrus/blob/6b6c3ec212e91f3c2a51fa6698c0209dd5208b20/sql/walrus--0.1.sql#L79

The two filter conditions

    format('%I.%I', c.table_schema, c.table_name)::regclass = new.entity
    and pg_catalog.has_column_privilege('anon', new.entity, c.column_name, 'SELECT')

are sometimes applied in parallel. Currently, the c.column_name is dynamic, but the table name is hard coded as new.entity. So if the second expression in the where clause executes before the first one, we can wind up asking postgres to look up permissions for a column that doesn't exist on the new.entity table.

This error is known to have occurred at least once in production resulting in

ERROR:  column "<some column>" of relation "<some table>" does not exist

This PR makes the table name also dynamic so that, even if we look up permissions about an irrelevant table/column, the result is ignored rather than throwing an error.


I have also opened an issue to move from information_schema to pg_catalog https://github.com/supabase/walrus/issues/43 for performance reasons, but that can be handled in a separate PR