Re: MD5 authentication needs help
| От | Stephen Frost |
|---|---|
| Тема | Re: MD5 authentication needs help |
| Дата | |
| Msg-id | 20150304182731.GG29780@tamriel.snowman.net обсуждение исходный текст |
| Ответ на | Re: MD5 authentication needs help (Bruce Momjian <bruce@momjian.us>) |
| Ответы |
Re: MD5 authentication needs help
|
| Список | pgsql-hackers |
* Bruce Momjian (bruce@momjian.us) wrote:
> On Wed, Mar 4, 2015 at 12:43:54PM -0500, Stephen Frost wrote:
> > > What does storing multiple hash(password || stoarage_salt) values do for
> > > us that session_salt doesn't already do?
> >
> > By storing a hash of the result of the challenge/response, we wouldn't
> > be susceptible to attacks where the user has gained access to the
> > contents of pg_authid because the values there would not be (directly)
> > useful for authentication. Today, an attacker can take what's in
> > pg_authid and directly use it to authenticate (which is what the
> > interwebs are complaining about).
> >
> > We wouldn't want to do that for just a single value though because then
> > there wouldn't be any value to the challenge/response system (which is
> > intended to prevent replay attacks where the attacker has sniffed a
> > value from the network and then uses that value to authenticate
> > themselves).
>
> So you are storing the password + storage-salt + session-saltX, where X
> is greater than the maximum number of login attempts? How do you know
> the attacker will not be given a salt that was already seen before?
The password isn't stored and I don't know what you're talking about
regarding the number of login attempts. Further, we don't know today if
an attacker has seen a particular challege/response sequence or not (nor
can we...) and we can certainly repeat it.
> > The only way we can keep the session salt random without breaking the
> > wireline protocol is to keep the raw data necessary for authentication
> > in pg_authid (as we do now) since we'd need that information to recreate
> > the results of the random session salt+user-hash for comparison.
> >
> > This is essentially a middle ground which maintains the existing
> > wireline protocol while changing what is in pg_authid to be something
> > that an attacker can't trivially use to authenticate. It is not a
>
> I don't understand how this works.
Ok, let me try to explain it another way.
The current system looks like this:
client has username and password
server has hash(username + password)
client:
send auth request w/ username and database
server:
send random salt to client
client:
send hash(hash(username + password) + salt) to server
server:
calculate hash(hash(username + password) + salt) compare to what client sent
What the interwebs are complaining about is that the
"hash(username + password)" piece that's stored in pg_authid is
sufficient to authenticate.
Here's what was proposed as an alternative which would prevent that
without breaking the existing wireline protocol:
client has username and password
server has user_salt, N * {salt, hash(hash(hash(username + password) + salt), user_salt)}
client:
send auth request w/ username and database
server:
picks random salt from the salts available for this user sends salt to the user
client:
send hash(hash(username + password) + salt) to server
server:
server calculates, using the data from the client, hash(FROM_CLIENT + user_salt) compares to hash stored for salt
chosen
This makes what is stored in pg_authid no longer directly useful for
authentication (similar to how Unix passwd-based authentication works)
because if the client sent any of those values, we'd add the user_salt
and hash it again and it wouldn't match what's stored.
This further makes what is sent over the network not directly
susceptible to a replay attack because the server has multiple values
available to pick for the salt to use and sends one at random to the
client, exactly how our current challenge/response replay-prevention
system works. The downside is that the number of possible values for
the server to send to prevent replay attacke is reduced from 2^32 to N.
To mitigate the replay risk we would, ideally, support a lock-out
mechanism. This won't help if the attacker has extended network access
though as we would almost certainly eventually go through all N
permutations for this user.
However, use of TLS would prevent the network-based attack vector.
Using TLS + the 'password' authentication mechanism would also achieve
the goal of making what is in pg_authid not directly useful for
authentication, but that would mean that the postmaster would see the
user's password (post-decryption), leading to a risk that the password
could be reused for access to other systems by a rogue server
administrator. Now, that's what SSH and *most* systems have had for
ages when it comes to password-based authentication and therefore it's
well understood in the industry and session-level encryption is
generally considered to avoid the network-based vector associated with
that approach.
For PG users, however, we encourage using md5 instead of password as we
consider that "better", but users familiar with SSH and other
unix-password based authentication mechanisms might, understandably,
think that MD5+TLS prevents both attack vectors, but it doesn't.
Password+TLS is what they would actually want to get the traditional
unix-password-style trade-offs.
Of course, the hashing algorithm used for all of the current
authentication systems we support is no longer generally considered
secure and that we use a non-random salt for storage (the username)
makes it worse.
Thanks!
Stephen
В списке pgsql-hackers по дате отправления: