Skip to content

0002_auth_users_exposed false positive: pg_depend join lacks a refclassid filter (cross-catalog OID collision) #171

Description

@hoybilli

Summary

lints/0002_auth_users_exposed.sql joins the view's rewrite dependencies to auth.users by OID only:

join pg_catalog.pg_depend d
    on d.refobjid = auth_users_pg_class.oid

There is no d.refclassid = 'pg_catalog.pg_class'::regclass predicate, so any pg_depend row from a view's rewrite whose refobjid numerically collides with auth.users' pg_class OID — but actually references an object in a different catalog (pg_proc, pg_type, …) — fires the lint.

Observed instance

On one of our projects, auth.users has pg_class OID 16499, and a public view calls a SECURITY DEFINER helper function whose pg_proc OID is also 16499. The view selects only from public tables (verified: zero relation dependency on auth.users), yet the advisor reports it as CRITICAL auth_users_exposed, and the "action required: security vulnerabilities" email goes out weekly.

Diagnostic query that shows the collision:

with au as (
  select oid from pg_class
  where relname = 'users' and relnamespace = 'auth'::regnamespace
),
rw as (
  select oid from pg_rewrite where ev_class = 'public.<your_view>'::regclass
)
select d.refclassid::regclass as ref_catalog,
       case when d.refclassid = 'pg_proc'::regclass then d.refobjid::regprocedure::text
            when d.refclassid = 'pg_class'::regclass then d.refobjid::regclass::text
            else d.refobjid::text end as ref_object,
       d.deptype
from pg_depend d, au, rw
where d.objid = rw.oid and d.refobjid = au.oid;

Result on the affected project: one row, ref_catalog = pg_proc, ref_object = <helper function>(text,uuid) — not a relation.

Suggested fix

Add the catalog filter to the join:

join pg_catalog.pg_depend d
    on d.refobjid = auth_users_pg_class.oid
    and d.refclassid = 'pg_catalog.pg_class'::regclass

(Other OID-equality joins in the lint suite may want the same audit.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions