Re: Several issues with postgres_fdw stats import

From: Etsuro Fujita <etsuro(dot)fujita(at)gmail(dot)com>
To: Corey Huinker <corey(dot)huinker(at)gmail(dot)com>
Cc: Fujii Masao <masao(dot)fujii(at)gmail(dot)com>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>, Noah Misch <noah(at)leadboat(dot)com>
Subject: Re: Several issues with postgres_fdw stats import
Date: 2026-09-22 11:35:58
Message-ID: CAPmGK16jVk+i2KMkkgR9ajoPdaUAinvcspkk5Bc6urbo2xYTMQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

I added Noah in CC.

On Fri, Sep 11, 2026 at 12:46 AM Corey Huinker <corey(dot)huinker(at)gmail(dot)com> wrote:
> On Thu, Sep 10, 2026 at 11:02 AM Etsuro Fujita <etsuro(dot)fujita(at)gmail(dot)com> wrote:
>> On Thu, Sep 10, 2026 at 3:59 PM Fujii Masao <masao(dot)fujii(at)gmail(dot)com> wrote:
>> > postgres_fdw stats import seems to have several potential issues.
>>
>> > (1) User-defined functions may be executed with unexpected privileges
>> >
>> > ANALYZE on a foreign table with import_stats disabled invokes
>> > user-defined functions (e.g., domain constraints) as the foreign table's
>> > owner. But, with import_stats enabled, they are invoked as the user
>> > running ANALYZE. So, if that user is a superuser, those functions would
>> > be run with superuser privileges. Could this be a security issue?
>>
>> Sorry, I don't follow this. Could you elaborate on it using an example?
>
> Me either. I think he's referring to generated columns, in which case the generated column wouldn't have a corresponding source column, hence would fail match_attrmap() and already falls back to sampling.

Here is an example provided by Noah, which doesn't involve
user-defined functions, but causes a security issue:

CREATE SERVER loopback FOREIGN DATA WRAPPER postgres_fdw OPTIONS
(dbname 'postgres');
CREATE USER MAPPING FOR CURRENT_USER SERVER loopback;
DROP ROLE IF EXISTS regress_ftowner;
CREATE ROLE regress_ftowner NOSUPERUSER;
GRANT USAGE ON FOREIGN SERVER loopback TO regress_ftowner;
GRANT CREATE ON SCHEMA public TO regress_ftowner;
CREATE TABLE secret (s text);
REVOKE ALL ON secret FROM PUBLIC;
INSERT INTO secret SELECT 'hunter2' FROM generate_series(1, 10);
ANALYZE secret;
SET ROLE regress_ftowner;
CREATE FOREIGN TABLE ft_secret (s text) SERVER loopback
OPTIONS (table_name 'secret', import_stats 'true');

-- the owner can neither read secret nor reach the remote server
SELECT * FROM ft_secret;
ERROR: user mapping not found for user "regress_ftowner", server "loopback"

-- which is good, BUT import_stats discloses data the owner cannot read
RESET ROLE;
ANALYZE ft_secret;
SET ROLE regress_ftowner;
SELECT most_common_vals FROM pg_stats WHERE tablename = 'ft_secret';
most_common_vals
------------------
{hunter2}
(1 row)

He provided a fix for this as well, which I'm attaching. The fix
addresses it by switching the userid to the foreign-table owner's
userid in analyze.c before calling ImportForeignStatistics(). I think
the fix is also reasonable in that it makes the identity handling
consistent between the sampling/import methods. So I will push and
back-patch the fix if no objections from others.

Best regards,
Etsuro Fujita

Attachment Content-Type Size
fix-stats-import-priv-handling.patch application/octet-stream 2.2 KB

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Etsuro Fujita 2026-09-22 11:38:52 Re: Several issues with postgres_fdw stats import
Previous Message Amit Langote 2026-09-22 11:31:27 Re: ri_Fast* crash w/ nullable UNIQUE constraint