On Mon, Sep 03, 2012 at 12:11:20AM -0400, Tom Lane wrote:
> Noah Misch <n...@leadboat.com> writes:
> > I don't think it's libpq's job to enforce security policy this way.  In any
> > event, it has no reason to presume an environment variable is a safer 
> > source.
> 
> One easy thing we could do that would at least narrow the risks is to
> only allow the executable's *directory* to be specified, hardwiring the
> executable file name to "postgres" (or "postgres.exe" I guess).

If the user has any interactive access to the machine, he could make a
/tmp/X/postgres symbolic link to the program of his choosing.

> I'm inclined to think though that environment variables *are* more
> secure in this context.  In the contrib/dblink example, such a
> restriction would certainly help a lot.

dblink_connect() should only let superusers specify standalone_datadir at all;
normal users have no business manipulating other data directories visible to
the backend running dblink.  For superusers, setting both standalone_datadir
and standalone_backend is fair game.

Trusting the environment over connection strings is a wrong policy for, say, a
setuid command-line program.  Suppose such a program passes libpq a fixed
connection string to access its embedded database.  The program will find
itself explicitly clearing this environment variable to regain safety.

> In any case, we should at
> least think of a way that an app using libpq can prevent this type
> of attack short of parsing the conn string for itself.

My recommendation to affected application authors is to pass the connection
string through PQconninfoParse().  Walk the array, validating or rejecting
arguments like "host" and "standalone_datadir".  For maximum safety, the
application would need to reject any unanticipated parameters.  We might
soften that by adding a "bool critical" field to PQconninfoOption that
documents whether the option must be understood by a program validating a
connection.  Compare the idea of the PNG chunk header's "ancillary" bit.
Parameters like "host" and "standalone_datadir" would be critical, while
"application_name" and "connect_timeout" would be ancillary.  But this is a
tough line to draw rigorously.


I was pondering the flexibility from letting the application fork/exec and
supply the client-side descriptor number(s) to libpq.  Suppose it wants to
redirect the backend's stderr to a file.  A single-threaded application would
temporarily redirect its own stderr while calling PQconnectdb().  In a
multithreaded application, that introduces a race condition when other threads
concurrently write to the normal stderr.  By handling redirection in its own
fork/exec code, the application can achieve the outcome safely.  Perhaps
offering this can wait until the feature constitutes a more general
embedded-database offering, though.

Thanks,
nm


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to