Skip to content

Revoke default PUBLIC EXECUTE on SECURITY DEFINER functions#362

Merged
tmablunar merged 1 commit intomasterfrom
feat/revoke-function-execute-from-public
Apr 22, 2026
Merged

Revoke default PUBLIC EXECUTE on SECURITY DEFINER functions#362
tmablunar merged 1 commit intomasterfrom
feat/revoke-function-execute-from-public

Conversation

@tmablunar
Copy link
Copy Markdown
Contributor

@tmablunar tmablunar commented Apr 22, 2026

Summary

  • PostgreSQL grants EXECUTE to PUBLIC by default on every new function. For CustomRole-managed SECURITY DEFINER functions (which typically run as an elevated owner like rds_superuser or rds_pgaudit), this meant any role on the cluster could invoke them — only the internal predicate checks (if any) stood between an arbitrary caller and the elevated action.
  • Emit REVOKE ALL ON FUNCTION ... FROM PUBLIC as the function owner before the existing GRANT EXECUTE TO <roleName> so only the owning CustomRole (and roles granted membership in it) can call the function.
  • The REVOKE runs via execWithRole like the surrounding DDL and is idempotent, so re-syncs stay consistent.

Test plan

  • go build ./... and go vet ./pkg/postgres/...
  • POSTGRESQL_CONTROLLER_INTEGRATION_HOST=localhost:5432 go test ./pkg/postgres/ (full package, all pass)
  • New integration test TestSyncDatabaseFunctions_revokesPublicExecute asserts PUBLIC has no EXECUTE after sync while the target role still does
  • CI green

🤖 Generated with Claude Code


Note

Medium Risk
Touches database privilege/ACL logic for SECURITY DEFINER functions; a mistake could break callers or unintentionally change access, though the change is narrowly scoped and covered by a new integration test.

Overview
SyncDatabaseFunctions now runs REVOKE ALL ON FUNCTION ... FROM PUBLIC (as the function owner) after ensuring ownership, removing PostgreSQL’s default PUBLIC EXECUTE grant on newly created SECURITY DEFINER functions before re-granting EXECUTE to the managed custom role.

Adds an integration test asserting the target role retains EXECUTE while PUBLIC does not, including a helper that correctly detects implicit default ACLs when proacl is NULL.

Reviewed by Cursor Bugbot for commit aeb9125. Configure here.

PostgreSQL grants EXECUTE to PUBLIC by default on new functions, which
meant any role on the cluster could invoke a CustomRole SECURITY DEFINER
function. Emit REVOKE ALL FROM PUBLIC before the GRANT so only the
owning CustomRole can execute it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@tmablunar tmablunar requested a review from a team as a code owner April 22, 2026 06:33
@github-actions github-actions Bot added the minor label Apr 22, 2026
@tmablunar tmablunar merged commit 86c8b1a into master Apr 22, 2026
6 checks passed
@tmablunar tmablunar deleted the feat/revoke-function-execute-from-public branch April 22, 2026 06:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants