* Bruce Momjian (br...@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
signature.asc
Description: Digital signature