Why this matters
The bug. The author wanted to give report_reader read access — but typed PUBLIC. In Postgres, PUBLIC is the implicit role every login is a member of, including built-in roles like pg_read_all_settings. Any future read-only or analytics user that connects to the database — even ones you haven't created yet — gets SELECT on orders.
The fix. Grant to the specific role you created on the previous line. After the migration runs, revoke the public grant if it slipped into production: REVOKE SELECT ON orders FROM PUBLIC;.
Lint your migrations. Tools like squawk (used by Sentry) flag GRANT … TO PUBLIC automatically in migration CI.
Review heuristic
Every endpoint that updates a user-owned object needs an explicit allowlist of fields it accepts. Object.assign and equivalents on raw request bodies are the smoking gun.
External reference: CWE-269: Improper Privilege Management.
↳ CWE-732; common in legacy Postgres setups.