DBX
DBX home
Acme ProductionPRODUCTIONExit Demo
Run Scan
Findings
Critical

Potential cross-tenant access through SECURITY DEFINER function

Affected:
public.get_invoice(uuid)
Category:
Tenant Isolation
Confidence:
high
First detected:
2026-08-12 11:04Z
Last verified:
2026-08-16 09:41Z

Summary

public.get_invoice(uuid) runs with the privileges of its owner, is executable by authenticated, and reads public.invoices without an ownership constraint in the evaluated path.

Why this matters

Row Level Security on public.invoices is not applied inside a definer-rights function. Any signed-in user who can guess or enumerate an identifier can retrieve records belonging to another organization, and the function is reachable directly over the REST RPC endpoint.

Evidence

Role
authenticated
Object
public.get_invoice(uuid)
Function security
SECURITY DEFINER
search_path
public, pg_temp
Executable by
authenticated
Target relation
public.invoices
Exposed via RPC
true
Tenant validation
No qualifying ownership constraint detected in evaluated path

Facts above were derived by the scanner from database metadata. No model output is involved in the verdict.

Technical details

pg_proc.prosecdef is true and EXECUTE is granted to authenticated. The function body selects from public.invoices, whose tenant column is never compared against the caller's resolved tenant. Because the function owner bypasses RLS, the table's policies do not constrain the result set.

Attack path

definerdefinerINTERNETINTERNET✓anonymousROLE⚠authenticatedROLE!Data APIPOSTGREST✓RPC/REST/V1/RPC⚠get_invoice()SECURITY DEFINER⚠refresh_usage_total…SECURITY DEFINER!v_customer_billingDEFINER VIEW!profilesRLS ENABLED!invoicesRLS ENABLED✓support_ticketsRLS ENABLED!webhook_endpointsRLS ENABLED⚠pricing_plansRLS ENABLED⚠subscriptionRLS DISABLED⚠_http_responseRLS DISABLED⚠avatarsPUBLIC BUCKET!

internet → authenticated → rest → rpc → fn:public.get_invoice(uuid) → public.invoices

recommended remediation

Unlock Full Audit (Demo)

Bottom 35% of Supabase projects we've scanned.
Production-Ready Fixes
Ready to scan your own database?
Buy Remediation Credits — $19

Includes 5 Activation Credits

Constrain the definer function to the caller's tenant, or drop definer rights and let RLS apply.

Current

Function: public.get_invoice(uuid) Security: DEFINER Reads: public.invoices

Recommended Review

This function reads tenant data using definer privileges but does not validate the caller's identity. DBXray cannot automatically generate the missing tenant constraint because it requires application-specific authorization logic. Either constrain the definer function to the caller's tenant, or drop definer rights (SECURITY INVOKER) and let RLS apply.

Expected security effect

  • Authentication required
  • Tenant ownership enforced inside the definer boundary
  • Cross-tenant access path removed
  • EXECUTE narrowed to authenticated

No migration generated — application intent required.

Compatibility risk

high

Internal jobs that call this function outside a user session will resolve no tenant and receive zero rows. Give them a separate service-role path.

DBX never applies SQL to your database.