Menu

1 / 2

How `OR` in a Postgres RLS policy leaked every flagged row to every user

DEV Community·Diven Rastdus·6 months ago
#zSo76YlP
#how#part#postgres#policy#every
Reading 0:00
15s threshold

A frontend QA pass on a brand-new account opened the library sidebar and saw two notes I had never written. They were public seed entries from a different user. Same UUIDs across every fresh account I tested.

This is a post-mortem of how multiple Postgres Row Level Security policies on the same table, glued together by OR , returned every flagged row to every authenticated user. And how the application layer trusted RLS to be a backstop and added zero filters of its own.

The fix shipped a few hours after the bug was found. Here is what happened, what I changed, and what I would do differently next time.

The setup

Single table, multi-user app. Each row has a user_id and a boolean is_public . The product has a private surface (your own notes) and a planned public surface (a shared atlas of notes you opt-in to publish).…

Continue reading — create a free account

Join HashtagPLUS to read full articles, follow hashtags, vote, and join the conversation.