Repository navigation
Stop exposing ip_hash to anon and remove anon write grants - #36
Merged
Merged
Conversation
The public engagement tables granted the anon role SELECT on ip_hash and INSERT, UPDATE and DELETE on every table and view. ip_hash is a salted server-set value used only for abuse limiting, so clients should never read it, and every write already goes through the server with the service role. The anon count helpers now count a named column instead of "*", so a column-level SELECT that omits ip_hash does not deny them. The SQL that applies the grant changes lives in docs/anon-privileges-hardening.sql.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two defense-in-depth fixes on the public engagement tables (comments, reactions, the community wall, CV downloads, the moderation log), on top of the row-level security that is already there. Found by a read-only review of the site's public REST tables.
1. anon could read ip_hash
ip_hash is a salted, server-set value used only for abuse limiting and for the "delete my own comment" check, so no IP can be recovered from it, but one visitor's comments, reactions and wall notes could be linked by it. The anon role now has a column-level SELECT that omits ip_hash on the three readable tables, and no SELECT at all on the two tables that were never anon-readable.
2. anon had write grants it never used
The anon (and authenticated) role had INSERT, UPDATE and DELETE on every table and view. Row-level security refuses those writes today, but the grants should not be there. They are revoked, and default privileges no longer hand them to new tables. Every write goes through the server with the service role, which bypasses row-level security.
Code change
The two count helpers in
src/lib/supabase.tsusedselect("*"). A column-level SELECT that omits ip_hash would deny a*read, so they now count a named column instead. The count is identical.The grant changes are in
docs/anon-privileges-hardening.sql. I dry-ran them against the live database in a rolled-back transaction and confirmed anon can read every column except ip_hash, the count helpers work, the views still read, and anon writes are denied. The grants are applied to the database once this deploys, so the live reads switch to the named-column count first.