Allow postgres_fdw passwordless non-superuser conns with prior superuser permission

From: Craig Ringer <craig(at)2ndquadrant(dot)com>
To: PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Allow postgres_fdw passwordless non-superuser conns with prior superuser permission
Date: 2018-08-06 03:22:34
Message-ID: CAMsr+YEDh6P5fH5x1Z5oSdbxEK2eoZMZsofUnVUjKz1X2wfSjg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi all

Currently postgres_fdw cannot be used with 'cert' authentication, i.e.
client-certificate validation and cert cn => postgres username mapping. You
also can't use things like Kerberos, SSPI, etc with a superuser-created FDW
and username map.

To permit this, I'd like to allow postgres_fdw user mappings to be created
with a new 'permit_passwordless' option. Only the superuser is allowed to
create such a mapping. If it's set to true, we bypass the
check_conn_params(...)
connection-string password check and the connect_pg_server(...) check for
the conn using a password when a non-superuser establishes a connection.

This doesn't re-open CVE-2007-6601 because the superuser has to explicitly
grant the access.

To make SSL client certs work properly with FDWs, I'd also like to add a
libpq parameter 'sslpassword' parameter, which corresponds to the PgJDBC
parameter of the same name. This lets the superuser create user mappings
for ssl client cert auth that use a user-specific 'sslcert', 'sslkey', and
'sslpassword'. Users can't use each others' keys because they don't know
the key password, and they can't create passwordless user mappings anyway.
Without 'sslpassword' a non-superuser user could make a connection to an
'md5 clientcert=1' server using another users' client cert. It's a trivial
change.

Patches to follow shortly.

Detailed explanation.

postgres_fdw assumes that connections that do not specify a password in the
connstr and connections that lack a password on the user mapping are
insecure and rejects them for non-superusers with:

ERROR: password is required
DETAIL: Non-superuser cannot connect if the server does not request a
password.
HINT: Target server's authentication method must be changed.

or

ERROR: password is required
DETAIL: Non-superusers must provide a password in the user mapping.

See check_conn_params and connect_pg_server
in contrib/postgres_fdw/connection.c .

This is because of CVE-2007-6601 for dblink.

It's assuming that connections without passwords must therefore not have
anything to make sure the local postgres user is really the user authorized
to access the remote end as that remote postgres user. It's trying to stop
use of 'peer' or 'ident', which we shouldn't permit because we'd be
allowing the non-superuser to potentially authenticate as the (usually)
'postgres' system-user and gain access to a 'postgres' superuser db
account. Or the connection might be using a service file or .pgpass in the
'postgres' user's home directory, in which case again we don't want a
non-superuser able to use it.

For 'cert' authentication you don't want to assume that the non-superuser
should be allowed to use the client certificate's private key file from the
file system. We don't provide a way to provide the ssl key as a literal in
the postgres_fdw user mapping. Nor is there a way to store the ssl key
encrypted, and put the ssl key passphrase in the user mapping, making sure
that just the authorized user can access it.

The problem is that you can't then use 'cert' auth for postgres_fdw at all.

Nor can you authorize a non-superuser to use passwordless authentication if
you know your local server is configured securely (no 'trust', 'peer' or
'ident') and you *want* to authorize the user to use a service file,
pgpass, etc.

We should allow this if the user mapping creator is the superuser and they
explicitly mark the mapping as permit_passwordless. That won't let normal
users escalate.

If the superuser is the one creating the user mapping between local and
remote user IDs, then they're the ones delegating the access. They can
already GRANT mysuperuser TO public if they're feeling stupid; similarly,
if they CREATE USER MAPPING FOR public SERVER localhost OPTIONS
('permit_passwordless',
'true', ...) ... then it's on them if they have 'peer' or 'ident' enabled
on the server.

--
Craig Ringer http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Paul Guo 2018-08-06 04:11:26 Re: [Patch] Create a new session in postmaster by calling setsid()
Previous Message Bossart, Nathan 2018-08-06 03:12:16 Re: REINDEX and shared catalogs