> On Apr 20, 2021, at 5:54 AM, Robert Haas <robertmh...@gmail.com> wrote:
>
> On Tue, Apr 20, 2021 at 1:31 AM Mark Dilger
> <mark.dil...@enterprisedb.com> wrote:
>> I think you are conflating the concept of an operating system adminstrator
>> with the concept of the database superuser/owner.
>
> You should conflate those things, because there's no meaningful
> privilege boundary between them:
I understand why you say so, but I think the situation is more nuanced than
that.
> http://rhaas.blogspot.com/2020/12/cve-2019-9193.html
>
> If reading the whole thing is too much, scroll down to the part in
> fixed-width font and behold me trivially compromising the OS account
> using plperlu.
I think the question here is whether PostgreSQL is inherently insecure, meaning
that it cannot function unless installed in a way that would allow the database
superuser Bob to compromise the OS administered by Alice.
Magnus seems to object even to this formulation in his blog post,
https://blog.hagander.net/when-a-vulnerability-is-not-a-vulnerability-244/,
saying "a common setup is to only allow the postgres OS user itself to act as
superuser, in which case there is no escalation at all." He seems to view Bob
taking over the OS account as nothing more than Alice taking over her own
account, since nobody but Alice should ever be able to log in as Bob. At a
minimum, I think that means that Alice must trust PostgreSQL to contain zero
exploits. If database user Charlie can escalate his privileges to the level of
Bob, then Alice has a big problem. Assuming Alice is an average prudent system
administrator, she doesn't really want to trust that PostgreSQL is completely
exploit free. She just wants to quarantine it enough that she can sleep at
night.
I think we have made the situation for Alice a bit difficult. She needs to
make sure that whichever user the backend runs as does not have permission to
access anything beyond the PGDATA directory and a handful of postgres binaries,
otherwise Bob, and perhaps Charlie, can access them. She can do this most
easily with containers, or at least it seems so to me. The only binaries that
should be executable from within the container are "postgres", "locale", and
whichever hardened archive command, recovery command, and restore command Alice
wants to allow. The only shell that should be executable from within the
container should be minimal, maybe something custom written by Alice that only
works to recognize the very limited set of commands Alice wants to allow and
then forks/execs those commands without allowing any further shell magic.
"Copy to program" and "copy from program" internally call popen, which calls
the shell, and if Alice's custom shell doesn't offer to pipe anything to the
target program, Bob can't really do anything that way. "locale -a" doesn't
seem particularly vulnerable to being fed garbage, and in any event, Alice's
custom shell doesn't have to implement the pipe stream logic in that direction.
She could make it unidirectional from `locale -a` back to postgres. The
archive, recovery, and restore commands are internally invoked using system()
which calls those commands indirectly using Alice's shell. Once again, she
could write the shell to not pipe anything in either direction, which pretty
well prevents Bob from doing anything malicious with them.
Reading and writing postgresql data files seems a much trickier problem. The
"copy to file" and "copy from file" implementations don't go through the shell,
and Alice can't deny the database reading or writing the data directory, so
there doesn't seem to be any quarantine trick that will work. Bob can copy
arbitrary malicious content to or from that directory. I don't see how this
gets Bob any closer to compromising the OS account, though. All Bob is doing
is messing up his own database. Even if corrupting these files convinces the
postgres backend to attempt to write somewhere else in the system, the
container should be sufficient to prevent it from actually succeeding outside
its own data directory.
The issue of the pg_read_file() sql function, and similar functions, would seem
to fall into the same category as "copy to file" and "copy from file". Bob can
read and write his own data directory, but not anything else, assuming Alice
set up the container properly.
> I actually think this is a design error on our part. A lot of people,
> apparently including you, feel that there should be a privilege
> boundary between the PostgreSQL superuser and the OS user, or want
> such a boundary to exist.
I'm arguing that the boundary does currently (almost) exist, but is violated by
default, easy to further violate without realizing you are doing so,
inconvenient and hard to maintain in practice, requires segregating the
database superuser from whichever adminstrator(s) execute other tools, requires
being paranoid when running such tools against the database because any content
found therein could have been maliciously corrupted by the database
administrator in a way that you are not expecting, requires a container or
chroot jail and a custom shell, and this whole mess should not be made any more
difficult.
We could make this incrementally easier by finding individual problems which
have solutions generally acceptable to the community and tackling them one at a
time. I don't see there will be terribly many such solutions, though, if the
community sees no value in putting a boundary between Bob and Alice.
—
Mark Dilger
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company