Policy "Users can view profiles" does not constrain rows to a tenant
- Affected:
- public.profiles
- Category:
- Tenant Isolation
- Confidence:
- high
- First detected:
- 2026-08-12 11:04Z
- Last verified:
- 2026-08-16 09:41Z
Summary
The SELECT policy on public.profiles admits every authenticated caller and never references organization_id.
Why this matters
Any signed-in user can read rows belonging to other organizations, because the policy only proves that a session exists — not that it owns the row.
Evidence
- Relation
- public.profiles
- Policy
- Users can view profiles
- Command
- SELECT
- Roles
- authenticated
- USING
- auth.uid() IS NOT NULL
- Tenant column present
- organization_id
- Tenant validation
- No qualifying ownership constraint detected
Facts above were derived by the scanner from database metadata. No model output is involved in the verdict.
Technical details
pg_policies.qual evaluates to a session-existence check. The table exposes organization_id, which the evaluated path never references.
recommended remediation
Unlock the full security analysis
Buy full analysisScope the policy to organization_id using the tenant resolver.
Current
CREATE POLICY "Users can view profiles" ON public.profiles FOR SELECT TO authenticated USING (auth.uid() IS NOT NULL);
Proposed
CREATE POLICY "Users can view profiles" ON public.profiles FOR SELECT TO authenticated USING ( organization_id = current_tenant_owner() );
Expected security effect
- Authentication required
- Tenant ownership enforced
- Cross-tenant read path removed
Compatibility risk
low
Callers relying on reading records outside their organization will start receiving zero rows. Verify admin tooling uses a privileged path.