Install script grants ALL on net tables to PUBLIC, which project owners cannot revoke
Maintainers usually reply within 2 days
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 42/100
Research direction
Start with the GRANT statements in sql/pg_net.sql and sql/pg_net--0.11.0--0.12.0.sql, then inspect the upgrade scripts and the SECURITY INVOKER functions named in the issue. Work out which named roles need access while preserving their ability to enqueue requests; done means install and upgrade grants protect the tables without granting all privileges to PUBLIC.
Written by the indexing model from the issue text.
Description
Summary
The install script grants all privileges on the net tables to PUBLIC:
-- sql/pg_net.sql (and since sql/pg_net--0.11.0--0.12.0.sql)
grant usage on schema net to PUBLIC;
grant all on all sequences in schema net to PUBLIC;
grant all on all tables in schema net to PUBLIC;
On a Supabase project running pg_net 0.20.0, this is what we see:
net.http_request_queue {supabase_admin=arwdDxtm/supabase_admin,=arwdDxtm/supabase_admin}
net._http_response {supabase_admin=arwdDxtm/supabase_admin,=arwdDxtm/supabase_admin}
schema net {..., =U/supabase_admin, ...}
So every role in the database, including anon and authenticated, can do the following:
- INSERT into
net.http_request_queue, which makes the database send arbitrary HTTP requests. - SELECT from
net._http_response, which can expose other callers' response bodies and headers. - UPDATE, DELETE and TRUNCATE either table.
For anon and authenticated, PostgREST only reaches this if net is in the exposed schemas. But any role with a SQL session gets it: a custom role, or a SECURITY INVOKER function running as the caller.
Why project owners can't fix it themselves
- The grant goes to
PUBLICand comes from the extension's install script. Supabase'sextensions.grant_pg_net_access()event trigger grants to named roles only. revoke ... from PUBLICaspostgreshas no effect:supabase_admingranted it, and only the grantor can revoke.- Since 0.12.0,
net.http_getandnet.http_postareSECURITY INVOKER, so the roles that legitimately enqueue requests (postgres,supabase_functions_admin,service_role) rely on that same grant. A blanket revoke would break them unless they get explicit grants.
Our workaround is a BEFORE INSERT OR UPDATE OR DELETE trigger plus a statement-level TRUNCATE trigger on net.http_request_queue that reject any role not on an allow-list. It works, but it's a band-aid on every project.
Ask
Could the install and upgrade scripts grant to named roles instead of PUBLIC? For example, postgres, supabase_functions_admin and service_role, which the Supabase event trigger already handles. Failing that, could project owners be allowed to revoke the PUBLIC grant?
Environment: Supabase hosted, Postgres 17.6, pg_net 0.20.0.
- Dominant language
- Python
- Stars
- 376
- Forks
- 44
- Avg merge
- 5d 11h
- Merged PRs (30d)
- 16
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from supabase/pg_net
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
supabase/pg_net#235 · 1 comment ·
Maintainers usually reply within 2 days
-
idea
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
supabase/pg_net#159 · 1 reaction ·
Maintainers usually reply within 2 days
-
Difficulty 5/5 Over a week Newbie friendliness 20/100
Maintainers usually reply within 2 days
-
Difficulty 3/5 1-2 days Newbie friendliness 72/100
Maintainers usually reply within 2 days
-
Difficulty 4/5 3-5 days Newbie friendliness 48/100
supabase/pg_net#321 · 1 comment ·
Maintainers usually reply within 2 days
Similar issues
-
area:scripts area:tests bug priority:later
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Ikalus1988/MisakaNet#4358 ·
Maintainers usually reply within 1 day
-
Discovered ports from service discovery are never propagated to modules in Module.load()Possibly taken @vishalmore90 claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
OWASP/Nettacker#1828 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 1/5 Under an hour Newbie friendliness 88/100
aws-samples/sample-per-model-bedrock#708 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
sjkim1127/Reversecore_MCP#365 ·
Maintainers usually reply within 1 day