mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
chore: Update the linter with the latest code (#23271)
Update the linter with the latest code.
This commit is contained in:
1 parent
471a4fe76d
commit
e50aecc594
1 file changed
+81
-43
@@ -90,22 +90,22 @@ select
|
||||
) as detail,
|
||||
'https://supabase.com/docs/guides/database/database-linter?lint=0002_auth_users_exposed' as remediation,
|
||||
jsonb_build_object(
|
||||
'schema', 'public',
|
||||
'schema', n.nspname,
|
||||
'name', c.relname,
|
||||
'type', 'view',
|
||||
'exposed_to', array_remove(array_agg(DISTINCT case when pg_catalog.has_table_privilege('anon', c.oid, 'SELECT') then 'anon' when pg_catalog.has_table_privilege('authenticated', c.oid, 'SELECT') then 'authenticated' end), null)
|
||||
) as metadata,
|
||||
format('auth_users_exposed_%s_%s', 'public', c.relname) as cache_key
|
||||
format('auth_users_exposed_%s_%s', n.nspname, c.relname) as cache_key
|
||||
from
|
||||
-- Identify the oid for auth.users
|
||||
pg_catalog.pg_class auth_users_pg_class
|
||||
pg_catalog.pg_class auth_users_pg_class
|
||||
join pg_catalog.pg_namespace auth_users_pg_namespace
|
||||
on auth_users_pg_class.relnamespace = auth_users_pg_namespace.oid
|
||||
and auth_users_pg_class.relname = 'users'
|
||||
and auth_users_pg_namespace.nspname = 'auth'
|
||||
-- Depends on auth.users
|
||||
on auth_users_pg_class.relnamespace = auth_users_pg_namespace.oid
|
||||
and auth_users_pg_class.relname = 'users'
|
||||
and auth_users_pg_namespace.nspname = 'auth'
|
||||
-- Depends on auth.users
|
||||
join pg_catalog.pg_depend d
|
||||
on d.refobjid = auth_users_pg_class.oid
|
||||
on d.refobjid = auth_users_pg_class.oid
|
||||
join pg_catalog.pg_rewrite r
|
||||
on r.oid = d.objid
|
||||
join pg_catalog.pg_class c
|
||||
@@ -116,7 +116,6 @@ from
|
||||
on d.refobjid = pg_class_auth_users.oid
|
||||
where
|
||||
d.deptype = 'n'
|
||||
and n.nspname = 'public'
|
||||
and (
|
||||
pg_catalog.has_table_privilege('anon', c.oid, 'SELECT')
|
||||
or pg_catalog.has_table_privilege('authenticated', c.oid, 'SELECT')
|
||||
@@ -132,7 +131,7 @@ where
|
||||
-- Standard View, accessible to anon or authenticated that is security_definer
|
||||
(
|
||||
c.relkind = 'v' -- v for view
|
||||
-- Exclude security invoker views
|
||||
-- Exclude security invoker views
|
||||
and not (
|
||||
lower(coalesce(c.reloptions::text,'{}'))::text[]
|
||||
&& array[
|
||||
@@ -147,7 +146,7 @@ where
|
||||
-- Standard View, security invoker, but no RLS enabled on auth.users
|
||||
(
|
||||
c.relkind in ('v') -- v for view
|
||||
-- is security invoker
|
||||
-- is security invoker
|
||||
and (
|
||||
lower(coalesce(c.reloptions::text,'{}'))::text[]
|
||||
&& array[
|
||||
@@ -157,11 +156,13 @@ where
|
||||
'security_invoker=on'
|
||||
]
|
||||
)
|
||||
and not pg_class_auth_users.relrowsecurity
|
||||
and not pg_class_auth_users.relrowsecurity
|
||||
)
|
||||
)
|
||||
group by
|
||||
c.relname, c.oid)
|
||||
n.nspname,
|
||||
c.relname,
|
||||
c.oid)
|
||||
union all
|
||||
(
|
||||
with policies as (
|
||||
@@ -219,18 +220,38 @@ where
|
||||
'_timescaledb_internal', 'auth', 'cron', 'extensions', 'graphql', 'graphql_public', 'information_schema', 'net', 'pgroonga', 'pgsodium', 'pgsodium_masks', 'pgtle', 'pgbouncer', 'pg_catalog', 'pgtle', 'realtime', 'repack', 'storage', 'supabase_functions', 'supabase_migrations', 'tiger', 'topology', 'vault'
|
||||
)
|
||||
and (
|
||||
-- Example: auth.uid()
|
||||
(
|
||||
-- Example: auth.uid()
|
||||
qual ~ '(auth)\\.(uid|jwt|role|email)\\(\\)'
|
||||
-- Example: select auth.uid()
|
||||
and lower(qual) !~ 'select\\s+(auth)\\.(uid|jwt|role|email)\\(\\)'
|
||||
qual like '%auth.uid()%'
|
||||
and lower(qual) not like '%select auth.uid()%'
|
||||
)
|
||||
or
|
||||
(
|
||||
-- Example: auth.uid()
|
||||
with_check ~ '(auth)\\.(uid|jwt|role|email)\\(\\)'
|
||||
-- Example: select auth.uid()
|
||||
and lower(with_check) !~ 'select\\s+(auth)\\.(uid|jwt|role|email)\\(\\)'
|
||||
or (
|
||||
qual like '%auth.jwt()%'
|
||||
and lower(qual) not like '%select auth.jwt()%'
|
||||
)
|
||||
or (
|
||||
qual like '%auth.role()%'
|
||||
and lower(qual) not like '%select auth.role()%'
|
||||
)
|
||||
or (
|
||||
qual like '%auth.email()%'
|
||||
and lower(qual) not like '%select auth.email()%'
|
||||
)
|
||||
or (
|
||||
with_check like '%auth.uid()%'
|
||||
and lower(with_check) not like '%select auth.uid()%'
|
||||
)
|
||||
or (
|
||||
with_check like '%auth.jwt()%'
|
||||
and lower(with_check) not like '%select auth.jwt()%'
|
||||
)
|
||||
or (
|
||||
with_check like '%auth.role()%'
|
||||
and lower(with_check) not like '%select auth.role()%'
|
||||
)
|
||||
or (
|
||||
with_check like '%auth.email()%'
|
||||
and lower(with_check) not like '%select auth.email()%'
|
||||
)
|
||||
))
|
||||
union all
|
||||
@@ -377,6 +398,7 @@ from
|
||||
) act(cmd)
|
||||
where
|
||||
c.relkind = 'r' -- regular tables
|
||||
and p.polpermissive -- policy is permissive
|
||||
and n.nspname not in (
|
||||
'_timescaledb_internal', 'auth', 'cron', 'extensions', 'graphql', 'graphql_public', 'information_schema', 'net', 'pgroonga', 'pgsodium', 'pgsodium_masks', 'pgtle', 'pgbouncer', 'pg_catalog', 'pgtle', 'realtime', 'repack', 'storage', 'supabase_functions', 'supabase_migrations', 'tiger', 'topology', 'vault'
|
||||
)
|
||||
@@ -568,17 +590,23 @@ from
|
||||
and dep.deptype = 'e'
|
||||
where
|
||||
c.relkind = 'v'
|
||||
and n.nspname = 'public'
|
||||
and (
|
||||
pg_catalog.has_schema_privilege('anon', n.nspname, 'USAGE')
|
||||
or pg_catalog.has_schema_privilege('authenticated', n.nspname, 'USAGE')
|
||||
)
|
||||
and n.nspname not in (
|
||||
'auth', 'cron', 'extensions', 'graphql', 'graphql_public', 'information_schema', 'net', 'pgsodium', 'pgsodium_masks', 'pgbouncer', 'pg_catalog', 'pgtle', 'realtime', 'storage', 'supabase_functions', 'supabase_migrations', 'vault'
|
||||
)
|
||||
and dep.objid is null -- exclude views owned by extensions
|
||||
and not (
|
||||
lower(coalesce(c.reloptions::text,'{}'))::text[]
|
||||
&& array[
|
||||
'security_invoker=1',
|
||||
'security_invoker=true',
|
||||
'security_invoker=yes',
|
||||
'security_invoker=on'
|
||||
]
|
||||
))
|
||||
and not (
|
||||
lower(coalesce(c.reloptions::text,'{}'))::text[]
|
||||
&& array[
|
||||
'security_invoker=1',
|
||||
'security_invoker=true',
|
||||
'security_invoker=yes',
|
||||
'security_invoker=on'
|
||||
]
|
||||
))
|
||||
union all
|
||||
(
|
||||
select
|
||||
@@ -648,12 +676,18 @@ from
|
||||
on c.relnamespace = n.oid
|
||||
where
|
||||
c.relkind = 'r' -- regular tables
|
||||
and n.nspname = 'public'
|
||||
-- RLS is disabled
|
||||
and not c.relrowsecurity)
|
||||
and not c.relrowsecurity
|
||||
and (
|
||||
pg_catalog.has_schema_privilege('anon', n.nspname, 'USAGE')
|
||||
or pg_catalog.has_schema_privilege('authenticated', n.nspname, 'USAGE')
|
||||
)
|
||||
and n.nspname not in (
|
||||
'_timescaledb_internal', 'auth', 'cron', 'extensions', 'graphql', 'graphql_public', 'information_schema', 'net', 'pgroonga', 'pgsodium', 'pgsodium_masks', 'pgtle', 'pgbouncer', 'pg_catalog', 'pgtle', 'realtime', 'repack', 'storage', 'supabase_functions', 'supabase_migrations', 'tiger', 'topology', 'vault'
|
||||
))
|
||||
union all
|
||||
(
|
||||
select
|
||||
select
|
||||
'extension_in_public' as name,
|
||||
'WARN' as level,
|
||||
'EXTERNAL' as facing,
|
||||
@@ -679,6 +713,10 @@ where
|
||||
-- plpgsql is installed by default in public and outside user control
|
||||
-- confirmed safe
|
||||
pe.extname not in ('plpgsql')
|
||||
-- Scoping this to public is not optimal. Ideally we would use the postgres
|
||||
-- search path. That currently isn't available via SQL. In other lints
|
||||
-- we have used has_schema_privilege('anon', 'extensions', 'USAGE') but that
|
||||
-- is not appropriate here as it would evaluate true for the extensions schema
|
||||
and pe.extnamespace::regnamespace::text = 'public')
|
||||
union all
|
||||
(
|
||||
@@ -726,13 +764,13 @@ where
|
||||
'_timescaledb_internal', 'auth', 'cron', 'extensions', 'graphql', 'graphql_public', 'information_schema', 'net', 'pgroonga', 'pgsodium', 'pgsodium_masks', 'pgtle', 'pgbouncer', 'pg_catalog', 'pgtle', 'realtime', 'repack', 'storage', 'supabase_functions', 'supabase_migrations', 'tiger', 'topology', 'vault'
|
||||
)
|
||||
and (
|
||||
-- Example: auth.jwt() -> 'user_metadata'
|
||||
-- False positives are possible, but it isn't practical to string match
|
||||
-- If false positive rate is too high, this expression can iterate
|
||||
qual like '%auth.jwt()%user_metadata%'
|
||||
or qual like '%current_setting(%request.jwt.claims%)%user_metadata%'
|
||||
or with_check like '%auth.jwt()%user_metadata%'
|
||||
or with_check like '%current_setting(%request.jwt.claims%)%user_metadata%'
|
||||
-- Example: auth.jwt() -> 'user_metadata'
|
||||
-- False positives are possible, but it isn't practical to string match
|
||||
-- If false positive rate is too high, this expression can iterate
|
||||
qual like '%auth.jwt()%user_metadata%'
|
||||
or qual like '%current_setting(%request.jwt.claims%)%user_metadata%'
|
||||
or with_check like '%auth.jwt()%user_metadata%'
|
||||
or with_check like '%current_setting(%request.jwt.claims%)%user_metadata%'
|
||||
))`.trim()
|
||||
|
||||
// Array of all lint rules we handle right now.
|
||||
|
||||
Reference in new issue
Block a user