Re: sandboxing untrusted code - Mailing list pgsql-hackers

From Robert Haas
Subject Re: sandboxing untrusted code
Date
Msg-id CA+TgmoZgODUbMEcogibZJejmQWky3rnHfT50_n_DWU7oLm2ghA@mail.gmail.com
Whole thread
In response to sandboxing untrusted code  (Robert Haas <robertmhaas@gmail.com>)
Responses Re: sandboxing untrusted code
List pgsql-hackers
On Thu, Aug 31, 2023 at 11:25 AM Robert Haas <robertmhaas@gmail.com> wrote:
> With those definitions in hand, I think it's possible to propose a
> meaningful security model:
>
> Rule #1: If the current user does not trust the provider, the code is
> fully sandboxed.
> Rule #2: If the session user does not trust the provider either of the
> currently-running code or of any other code that's still on the call
> stack, the code is partially sandboxed.

Returning to this topic after some time, I have realized that both of
these rules are inadequate.

For example, suppose Alice is a superuser. She writes a SECURITY
INVOKER function which does something terrible, like running
pg_terminate_backend() or using COPY TO/FROM PROGRAM to overwrite
files in the data directory or deleting all the rows from pg_proc or
calling pg_read_file(). As a superuser, she's entitled to do this sort
of thing. She can write that function, and if she wishes, she can
execute it.

But now let's further suppose that Bob is a non-superuser who wishes
to ruin Alice's life. If he can induce Alice to call *her own terrible
function* at a time of his choosing, and perhaps with arguments of his
choosing, he wins. So, he does something sneaky, like call it from a
trigger function attached to a table that he owns, hoping that Alice
will eventually do something that fires the trigger function.

This is the sort of attack that you'd hope that my sandboxing proposal
(perhaps misnamed -- what should it be called?) would prevent. And if
Bob tried to do the terrible things *directly* from his trigger
function, it would. Rule #1 would apply, and the code would be
prevented from doing anything destructive. But, in this scenario, Bob
uses Alice's own function as an intermediary, and so rule #1 doesn't
apply, because the provider of all the code inside Alice's function is
Alice, so the attack succeeds.

Rule #2 is also flawed, because the problematic code need not be on
the call stack at the time the attack is occurring. If, for example,
Bob writes a function and somehow induces Alice to call it, the
function call might get inlined, and the inlined code might be a call
to Alice's terrible function. Now, when Alice accidentally executes
Bob's malicious function, every function on the run-time call stack
belongs to Alice, so the call stack is incapable of warning us that
Bob is a danger. To do better, we need to know that the Bob had a hand
in inducing Alice to call the terrible function, even though at the
time it is actually called none of his code is running
anywhere.

The moral in both cases is that it's not sufficient for the immediate
provider of a bit of code to be trustworthy. If there's an
untrustworthy party anywhere in the chain of events that led up to
running that code, that party might have chosen the time at which the
code was executed or the arguments with which it was executed in an
attempt to do something nefarious.

In retrospect, this seems sort of obvious. To scam someone IRL, you
don't have to actually get them to hand over the login for their
online banking account. It's true that, if you do, you've successfully
scammed them: you can just log in and transfer all their money to
yourself. But it works just as well to induce them hand over their
money under some sort of false premise. In that case, you never
directly take an action with their credentials: they perform the
action for you, all the while believing that they are acting in their
own interests. This is not quite a perfect analogy to the sort of
situation under discussion here, but it's somewhat similar. As soon as
the attacker has *any* influence over what code the victim calls,
there's a danger of a "confused deputy" attack.

--
Robert Haas
EDB: http://www.enterprisedb.com



pgsql-hackers by date:

Previous
From: Dean Rasheed
Date:
Subject: Re: [BUG] ON CONFLICT DO UPDATE SET x = EXCLUDED. errors or silently writes NULL
Next
From: Antonin Houska
Date:
Subject: Re: Adding REPACK [concurrently]