Skip to content

SECURITY DEFINER guard in function__arg_to_regprocedure blocks legitimate trusted-extension installs #87

Description

@jnasbyupgrade

The SECURITY DEFINER misuse guard in _cat_tools.function__arg_to_regprocedure produces a false positive that blocks installing cat_tools (or anything built on it) as a PostgreSQL trusted extension.

The guard

_cat_tools.function__arg_to_regprocedure is called by other cat_tools helpers while resolving a function's argument types (e.g. cat_tools.function__arg_types_text and the create_function-style logic that depends on it). It contains:

IF current_user != session_user THEN
  RAISE EXCEPTION 'potential use of SECURITY DEFINER detected' ...

with an inline hint noting this check "can cause false positives if SET ROLE is used."

Why it's a false positive for trusted extensions

PostgreSQL's trusted-extension mechanism (a .control file with trusted = true) lets a non-superuser role that only has CREATE privilege run CREATE EXTENSION cat_tools. By design, the install script then runs with an elevated current_user (the extension's owning/bootstrap identity) while session_user stays the real, unprivileged caller who issued the CREATE EXTENSION statement. That's PostgreSQL's documented trusted-extension elevation, not a SECURITY DEFINER injection.

Because current_user != session_user is exactly the state trusted-extension installation produces, the guard fires immediately and aborts the install with potential use of SECURITY DEFINER detected, even though no actual SECURITY DEFINER misuse occurred.

Reproduction

  1. Add trusted = true to cat_tools.control.
  2. Create a plain role with NOINHERIT and only CREATE privilege on the target database.
  3. Grant that role to the installing session and SET ROLE to it.
  4. Run CREATE EXTENSION cat_tools.

Result: install fails immediately with potential use of SECURITY DEFINER detected. With the guard removed (or made aware of legitimate trusted-extension elevation), the rest of the install completes without issue — the guard is the sole blocker.

Impact

This makes it impossible to install cat_tools, or any downstream extension whose install script calls into these argument-resolution helpers, via PostgreSQL's non-superuser trusted-extension path. It forces a real-superuser install even in environments (e.g. managed Postgres services) that otherwise support non-superuser extension management for extensions that opt in via trusted = true.

Ask

Some way to distinguish "legitimate trusted-extension elevation" from "actual SECURITY DEFINER function misuse" — for example, checking whether the call is happening during CREATE EXTENSION's own execution context (if Postgres exposes that), or another approach the maintainer prefers. Leaving the exact fix open here since the guard's full original threat model isn't known from the outside.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions