Skip to content

RLS hardening: wrap current_setting() in (select …) for per-statement eval (+ optional FORCE RLS) #2

Description

@dmitrymaranik

Hi, and thanks for OpenStudy. I ran a static RLS analyzer (pgrls) over migrations/ and spotted two small hardening items:

  1. Perf: the *_user_isolation policies (~16, on courses / deliverables / app_settings / …) call current_setting('app.user_id', …) per row in USING. Wrapping it in (select current_setting(…)) makes it a per-statement InitPlan (the Supabase-documented RLS perf pattern) — predicate-equivalent, so visibility is unchanged.
  2. Defense-in-depth: the RLS tables ENABLE but don't FORCE ROW LEVEL SECURITY, so the table-owner role still bypasses the policies. ALTER TABLE … FORCE ROW LEVEL SECURITY closes that — unless a SECURITY DEFINER path relies on owner-bypass, in which case it's worth a deliberate skip.

Happy to send a PR for the (select …) wrap (the safe, mechanical one) if useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    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