HomeRulesBND008
BND008 · High severity

RLS policy trusts user-editable authentication metadata.

A signed JWT is not enough when the authorization value inside it was supplied by the user. Attackers can modify user_metadata and manufacture a tenant claim a policy mistakenly trusts.

Detection condition

The rule reports client-accessible policies whose USING or WITH CHECK expressions read raw_user_meta_data, or user_metadata from auth.jwt() or request.jwt.claims. It does not report server-controlled app_metadata claims or policies limited to trusted server roles.

Why it matters

Supabase users can update user_metadata through authentication APIs. A policy that treats a tenant ID, role, or authorization flag from that object as trusted can turn a profile edit into cross-tenant access.

Typical remediation

Prefer a protected membership table correlated to both auth.uid() and the tenant column on the row. Server-controlled app_metadata can hold authorization claims, but remember that JWT values may remain stale until the token is refreshed.

Use protected membership datasql
using (exists (
  select 1
  from public.organization_members memberships
  where memberships.organization_id = projects.organization_id
    and memberships.user_id = auth.uid()
));
Protect the boundary

Make tenant isolation a repeatable pull-request check.

Run the deterministic scanner locally without database credentials, then add Cloud only when your team needs shared history.

Find unsafe metadata policies Read the quickstart