Thread: Serious problem within authentication subsystem in 7.0

Serious problem within authentication subsystem in 7.0

From
Matt Sullivan
Date:
Hi,

Ok, I know the mailing list web page states: YOU MUST TRY ELSEWHERE FIRST! and
this should, technically speaking, be reported as a bug however given that the
security implications are potentially severe I thought here would be best in
the first instance.

I have only briefly looked into this problem as I have just now discovered it. 
Essentially, in our environment, we require password authentication as a
defacto.  However it appears that once a user has authenticated with the
backend it is possible for that user to trivially assume root dba privileges or
privileges of any other dba user.

To demonstrate the problem: 

Consider two systems: 
 pgsqlserver   192.168.1.1    - backend system pgsqlclient   192.168.1.2    - client system 
Our pg_hba.conf (on pgsqlserver) now looks something similar to: 
 local   all                                     password host    all     127.0.0.1       255.255.255.255 password host
  all     192.168.1.2     255.255.255.255 password
 

Now making connections from pgsqlclient (192.168.1.2) would require password
authentication.  To show that this works, entering an incorrect passwd...
 pgsqlclient:/home/matt 11:33am > psql -h pgsqlserver -U matt matt Password:  psql: Password authentication failed for
user'matt'
 

Now a correct password: 
 pgsqlclient:/home/matt 11:36am > psql -h pgsqlserver -U matt matt Password:  Welcome to psql, the PostgreSQL
interactiveterminal.  Type:  \copyright for distribution terms        \h for help with SQL commands        \? for help
oninternal slash commands        \g or terminate with semicolon to execute query        \q to quit  matt=> 
 

Ok, so at the top level password authentication works, now to the problem... 

Once authenticated it is possible to trivially assume another users identity
without further authentication e.g. 
 matt=> \c template1 postgres You are now connected to database template1 as user postgres. template1=# 

Or, assume any other users identity: 
 matt=> \c www www You are now connected to database www as user www. www=> 

Ouch. 

I have not tested to see if this is specific to the password authentication
method or a general problem relating to any of the supported methods and I have
limited time to investigate this at the moment.

Is there anyone who specifically maintains the authentication subsystem that I
could communicate with directly?  I would be interested to offer whatever
assistance I can. 


Regards,
Matt.



Re: Serious problem within authentication subsystem in 7.0

From
Tom Lane
Date:
Matt Sullivan <matt@sullivan.gen.nz> writes:
> Essentially, in our environment, we require password authentication as
> a defacto.  However it appears that once a user has authenticated with
> the backend it is possible for that user to trivially assume root dba
> privileges or privileges of any other dba user.

It appears that psql will auto-supply the previously entered password,
so if you were using the same password for all your accounts then this
might happen.  Otherwise it's pretty hard to believe.  That new
connection is to a new backend; there's no way for it to know that you
were previously connected.

Offhand I think it would be a good idea for psql to insist on a new
password if the \connect command gives a new user name...
        regards, tom lane


Re: Serious problem within authentication subsystem in 7.0

From
Matt Sullivan
Date:
On Mon, 22 May 2000, Tom Lane wrote:

> Matt Sullivan <matt@sullivan.gen.nz> writes:
> > Essentially, in our environment, we require password authentication as
> > a defacto.  However it appears that once a user has authenticated with
> > the backend it is possible for that user to trivially assume root dba
> > privileges or privileges of any other dba user.
> 
> It appears that psql will auto-supply the previously entered password,
> so if you were using the same password for all your accounts then this
> might happen.  Otherwise it's pretty hard to believe.  That new
> connection is to a new backend; there's no way for it to know that you
> were previously connected.
> 
> Offhand I think it would be a good idea for psql to insist on a new
> password if the \connect command gives a new user name...

Ok, phew...
 matt=> \c wwwdata wwwdata Password authentication failed for user 'wwwdata' Previous connection kept matt=> 

This would infer though that the passwd data is cached within each instance of
psql which could present it's own set of security risks. 
I would think that it should probably be *forgotton* after authentication is
established and required on any new \connect.  This might present some issues
with pg_dump etc. I guess though.


Matt.



Re: Serious problem within authentication subsystem in 7.0

From
Tom Lane
Date:
Matt Sullivan <matt@sullivan.gen.nz> writes:
> This would infer though that the passwd data is cached within each
> instance of psql which could present it's own set of security risks.

Yeah.  There's been discussion about that, and the consensus seems to
be that the advantages outweigh the very small risks.  (One of the
disadvantages of forgetting the password is that PQreset can't work...)

> I would think that it should probably be *forgotton* after
> authentication is established and required on any new \connect.  This
> might present some issues with pg_dump etc. I guess though.

pg_dump is actually pretty nearly useless in a password-auth
installation; to run the restore script, you'd have to manually enter
a password each time it hits a \connect command :-(.

The best idea I've heard for fixing this is to invent a quasi-suid
mechanism: the pg_dump script would be started as postgres (enter
password for same, once) and it would NOT do any \connect commands.
Instead it would issue some kind of "SET effective_user = 'name'"
command, which would determine the ownership assigned to subsequently-
created objects, but the backend would still remember that the user
was "really" postgres.  Presumably this SET command would only be
allowed to superusers, so the backend must remember that the user is
really postgres, or it'll reject SET effective_user commands after
the first one.

The devil is in the details, of course, and the details here would be
to figure out which operations should pay attention to effective_user
and which to the true userid.  But it seems doable.

(Hey Peter, wanna put this on your todo list for that privilege-system
work?)
        regards, tom lane


Re: Serious problem within authentication subsystem in 7.0

From
Tom Lane
Date:
Peter Eisentraut <e99re41@DoCS.UU.SE> writes:
> The assumption that the old password can be reused between
> password connections seems pretty unwise.

I think it's OK, and a useful convenience, if you are reconnecting with
the same username as before.  What I had in mind was to discard the
prior password if the \connect command specifies a username.
        regards, tom lane


Re: Serious problem within authentication subsystem in 7.0

From
Peter Eisentraut
Date:
Tom Lane writes:

> > The assumption that the old password can be reused between
> > password connections seems pretty unwise.
> 
> I think it's OK, and a useful convenience, if you are reconnecting with
> the same username as before.  What I had in mind was to discard the
> prior password if the \connect command specifies a username.

But if you have different passwords between databases then you are still
having the same problem, only at a different scale.

-- 
Peter Eisentraut                  Sernanders väg 10:115
peter_e@gmx.net                   75262 Uppsala
http://yi.org/peter-e/            Sweden



Re: Serious problem within authentication subsystem in 7.0

From
Tom Lane
Date:
Peter Eisentraut <peter_e@gmx.net> writes:
> But if you have different passwords between databases then you are still
> having the same problem, only at a different scale.

... which we do not have, at the moment; there's one password per user
per installation, and since psql's \connect doesn't allow reconnection
to a different postmaster (does it?) the same password should still work.
Unless it's been changed meanwhile, I suppose.

In any case, isn't psql's logic such that it will prompt again if the
previous password doesn't work?  I'd hate to think I only get one try to
enter my password correctly...
        regards, tom lane


Re: Serious problem within authentication subsystem in 7.0

From
Peter Eisentraut
Date:
Tom Lane writes:

> Peter Eisentraut <peter_e@gmx.net> writes:
> > But if you have different passwords between databases then you are still
> > having the same problem, only at a different scale.
> 
> ... which we do not have, at the moment; there's one password per user
> per installation,

No, pg_hba.conf allows per database passwords.

> In any case, isn't psql's logic such that it will prompt again if the
> previous password doesn't work?

No, it will only prompt you for a password if it notices one is required.
If that's wrong the connection attempt fails and you can try again (to
connect). That's reasonable enough I think.


-- 
Peter Eisentraut                  Sernanders väg 10:115
peter_e@gmx.net                   75262 Uppsala
http://yi.org/peter-e/            Sweden



Re: Serious problem within authentication subsystem in 7.0

From
Tom Lane
Date:
Peter Eisentraut <peter_e@gmx.net> writes:
>> ... which we do not have, at the moment; there's one password per user
>> per installation,

> No, pg_hba.conf allows per database passwords.

Oh you're right, I had forgotten about that barely-supported hack for
alternate password files.

>> In any case, isn't psql's logic such that it will prompt again if the
>> previous password doesn't work?

> No, it will only prompt you for a password if it notices one is required.
> If that's wrong the connection attempt fails and you can try again (to
> connect). That's reasonable enough I think.

Seems like if it inserts the old password and notices that the error is
'bogus password' then it should prompt you for a new one.

BTW, I notice that there seems to be a nasty portability bug in that
logic: it'll try to "free(prompted_password)" even if prompted_password
is NULL.  On a lot of systems that's a recipe for a coredump, or at
least used to be (is everyone ANSI enough now to get this right??)
        regards, tom lane