materializedViewInApi¶
Group security · Severity Warning · Recommended · Requires Supabase
Diagnostic splinter/security/materializedViewInApi
Note
This rule needs a Supabase database. It is skipped when the Supabase roles don't exist.
Description¶
Detects materialized views that are accessible over the Data APIs.
Remediation¶
See the Supabase database linter docs.
How to configure¶
{
"splinter": {
"rules": {
"security": {
"materializedViewInApi": "error"
}
}
}
}
SQL query¶
Show the query
(
select
'materialized_view_in_api' as "name!",
'Materialized View in API' as "title!",
'WARN' as "level!",
'EXTERNAL' as "facing!",
array['SECURITY'] as "categories!",
'Detects materialized views that are accessible over the Data APIs.' as "description!",
format(
'Materialized view \`%s.%s\` is selectable by anon or authenticated roles',
n.nspname,
c.relname
) as "detail!",
'https://supabase.com/docs/guides/database/database-linter?lint=0016_materialized_view_in_api' as "remediation!",
jsonb_build_object(
'schema', n.nspname,
'name', c.relname,
'type', 'materialized view'
) as "metadata!",
format(
'materialized_view_in_api_%s_%s',
n.nspname,
c.relname
) as "cache_key!"
from
pg_catalog.pg_class c
join pg_catalog.pg_namespace n
on n.oid = c.relnamespace
left join pg_catalog.pg_depend dep
on c.oid = dep.objid
and dep.deptype = 'e'
where
c.relkind = 'm'
and (
pg_catalog.has_table_privilege('anon', c.oid, 'SELECT')
or pg_catalog.has_table_privilege('authenticated', c.oid, 'SELECT')
)
and n.nspname = any(array(select trim(unnest(string_to_array(current_setting('pgrst.db_schemas', 't'), ',')))))
and n.nspname not in (
'_timescaledb_cache', '_timescaledb_catalog', '_timescaledb_config', '_timescaledb_internal', 'auth', 'cron', 'extensions', 'graphql', 'graphql_public', 'information_schema', 'net', 'pgmq', 'pgroonga', 'pgsodium', 'pgsodium_masks', 'pgtle', 'pgbouncer', 'pg_catalog', 'pgtle', 'realtime', 'repack', 'storage', 'supabase_functions', 'supabase_migrations', 'tiger', 'topology', 'vault'
)
and dep.objid is null)