Thread: Weak passwords and brute force attacks
Hi all, Host-based authentication and the other security mechanisms we have at the moment provide fairly rigorous security but it seems to me there are two mechanisms other authentication systems provide which we do not: testing of the strength of passwords and delaying response after an authentication failure. The password strength test is pretty self-explanatory: DBAs often have to hand out accounts to a range of real people who will be using anything from reporting apps to testing new applications etc. With strength testing, a DBA can at least ensure that a certain standard of complexity is met. The attached patch adds two GUCs called 'test_weak_passwords' and 'min_password_length'. If 'test_weak_passwords', passwords will be analyzed during CREATE and ALTER ROLE. It's not as simple the password being greater than min_password_length. I guess the GUC name is a bit confusing in that respect. Instead, what we do is add up the different character types (lower, upper, digits, etc) and for each character type missing, we reduce the hypothetical password length: the theory being that the longer the password, the harder to guess. Now, in the presence of encrypted passwords being sent across the wire, we can't do anything. So, we export the password strength tester to libpq. The second mechanism is the delay on authentication failure. The problem here is that a distributed application could attempt to brute force guess a password for a role. This could be fairly effective on a high speed LAN. So, the usual approach is to delay sending the failure message to the client for some period of time (specified in the patch by auth_failure_delay) to slow the progress of the password guesser. Naturally, environments where you cannot trust the local network sound like problem outside out scope. But, I see a lot of systems with sensitive company information (consider an HR system) which even employees should be denied access to. Authentication failure delay can be done with PAM but not everyone will be abke to use PAM. Any thoughts on these ideas? Thanks, Gavin
Gavin Sherry wrote: > Hi all, > > Host-based authentication and the other security mechanisms we have at the > moment provide fairly rigorous security but it seems to me there are two > mechanisms other authentication systems provide which we do not: testing > of the strength of passwords and delaying response after an authentication > failure. > > Frankly, if we're going to build this stuff in we need to expose the API for password checking at least. Many apps run as a given postgres user and set up application users and passwords as application level artifacts. > The password strength test is pretty self-explanatory: DBAs often have to > hand out accounts to a range of real people who will be using anything > from reporting apps to testing new applications etc. With strength > testing, a DBA can at least ensure that a certain standard of complexity > is met. The attached patch adds two GUCs called 'test_weak_passwords' and > 'min_password_length'. If 'test_weak_passwords', passwords will be > analyzed during CREATE and ALTER ROLE. It's not as simple the password > being greater than min_password_length. I guess the GUC name is a bit > confusing in that respect. Instead, what we do is add up the different > character types (lower, upper, digits, etc) and for each character type > missing, we reduce the hypothetical password length: the theory being that > the longer the password, the harder to guess. > > Now, in the presence of encrypted passwords being sent across the wire, we > can't do anything. So, we export the password strength tester to libpq. > That assumes you trust the client. So then you are protecting against stupidity, but not malice. But you are afraid that stupidity will open the door to malice ... > The second mechanism is the delay on authentication failure. The problem > here is that a distributed application could attempt to brute force guess > a password for a role. This could be fairly effective on a high speed LAN. > So, the usual approach is to delay sending the failure message to the > client for some period of time (specified in the patch by > auth_failure_delay) to slow the progress of the password guesser. > Naturally, environments where you cannot trust the local network sound > like problem outside out scope. But, I see a lot of systems with sensitive > company information (consider an HR system) which even employees should be > denied access to. > Arguably such systems should not be using standard password auth at all. SSL with client certs is probably the way to go. Relying on password strength checking and delay in such a case would be, to use David Fetter's recent phrase, putting lipstick on the md5 pig. > Authentication failure delay can be done with PAM but not everyone will be > abke to use PAM. > Well, pam_cracklib will do an outstanding job on all these issues for you. I'm not opposed to providing some of this stuff, although some does seem to be reinventing the wheel. But we should be careful about how much security we think we are really providing. cheers andrew
Gavin Sherry <swm@linuxworld.com.au> writes: > .... Instead, what we do is add up the different > character types (lower, upper, digits, etc) and for each character type > missing, we reduce the hypothetical password length: the theory being that > the longer the password, the harder to guess. Where did you get this design for a password strength checker? It doesn't sound like it has much to do with the algorithms commonly used for such things. > Now, in the presence of encrypted passwords being sent across the wire, we > can't do anything. So, we export the password strength tester to libpq. As already noted, that seems approximately useless. > The second mechanism is the delay on authentication failure. The problem > here is that a distributed application could attempt to brute force guess > a password for a role. This could be fairly effective on a high speed LAN. > So, the usual approach is to delay sending the failure message to the > client for some period of time (specified in the patch by > auth_failure_delay) to slow the progress of the password guesser. This is a waste of effort, unless you propose to put the delay into both the success and failure paths, which hardly seems acceptable. Otherwise a guesser need only abandon the connection attempt after X microseconds and try another password. regards, tom lane
On Tue, Dec 05, 2006 at 11:32:40AM -0500, Tom Lane wrote: > Gavin Sherry <swm@linuxworld.com.au> writes: > > Now, in the presence of encrypted passwords being sent across the wire, we > > can't do anything. So, we export the password strength tester to libpq. > As already noted, that seems approximately useless. Telling the users they are being stupid isn't useless - but yeah, it sounds like a domain that should be covered by a tool other than PostgreSQL. PAM sounds about right, and PAM already has this functionality. > > The second mechanism is the delay on authentication failure. The problem > > here is that a distributed application could attempt to brute force guess > > a password for a role. This could be fairly effective on a high speed LAN. > > So, the usual approach is to delay sending the failure message to the > > client for some period of time (specified in the patch by > > auth_failure_delay) to slow the progress of the password guesser. > This is a waste of effort, unless you propose to put the delay into both > the success and failure paths, which hardly seems acceptable. Otherwise > a guesser need only abandon the connection attempt after X microseconds > and try another password. Not a waste unless the caller isn't going to allow for missing a valid password after X+1 microseconds that was late due to network latency, and CPU scheduling. This isn't a real time system. Even halfing the number of password attempts doubles the time required to search a particular pattern space. Double is good. It's a tried and true method used by security systems around the world. Another tried and true approach is to deny a client for a period (10 seconds?) if they enter the same wrong password three times in a row. It really puts a wrench in the gears for any brute force strategy. But again, I would still prefer to avoid username/password entirely if security is a real concern. SSL certificates, Kerberos tokens, or operating system credentials (passed over UNIX sockets) appeal to me much more. If the patch is really small, and really portable, I would suggest it be adopted. For example, adding a sleep(1) after invalid passwords doesn't significantly add to the maintenance cost for the code, and it has a positive effect. Getting too complicated, however, would be a problem domain that PostgreSQL shouldn't be trying to address. Another perspective... :-) Cheers, mark -- mark@mielke.cc / markm@ncf.ca / markm@nortel.com __________________________ . . _ ._ . . .__ . . ._. .__ . . . .__ | Neighbourhood Coder |\/| |_| |_| |/ |_ |\/| | |_ | |/ |_ | | | | | | \ | \ |__ . | | .|. |__ |__ | \ |__ | Ottawa, Ontario, Canada One ring to rule them all, one ring to find them, one ring to bring them all and in the darkness bindthem... http://mark.mielke.cc/
* mark@mark.mielke.cc (mark@mark.mielke.cc) wrote: > On Tue, Dec 05, 2006 at 11:32:40AM -0500, Tom Lane wrote: > > Gavin Sherry <swm@linuxworld.com.au> writes: > > > Now, in the presence of encrypted passwords being sent across the wire, we > > > can't do anything. So, we export the password strength tester to libpq. > > As already noted, that seems approximately useless. > > Telling the users they are being stupid isn't useless - but yeah, it sounds > like a domain that should be covered by a tool other than PostgreSQL. > > PAM sounds about right, and PAM already has this functionality. PAM is simply not always an option, unless you want to figure out a way to use PAM modules without using /etc/passwd and company. Currently the only way to use PAM w/ password-changing done in PG is to chown all the various files and whatnot over to being owned by Postgres, which is a royal pain and a very ugly mess. I suppose another option would be to convince PG to run as root but that's not exactly an encouraged setup either. I wouldn't be against using cracklib (outside of PAM) tho. > > This is a waste of effort, unless you propose to put the delay into both > > the success and failure paths, which hardly seems acceptable. Otherwise > > a guesser need only abandon the connection attempt after X microseconds > > and try another password. > > Not a waste unless the caller isn't going to allow for missing a valid > password after X+1 microseconds that was late due to network latency, > and CPU scheduling. This isn't a real time system. Even halfing the > number of password attempts doubles the time required to search a > particular pattern space. Double is good. It's a tried and true method > used by security systems around the world. Another tried and true > approach is to deny a client for a period (10 seconds?) if they enter > the same wrong password three times in a row. It really puts a wrench > in the gears for any brute force strategy. I fully agree with this. > But again, I would still prefer to avoid username/password entirely if > security is a real concern. SSL certificates, Kerberos tokens, or > operating system credentials (passed over UNIX sockets) appeal to me > much more. Sure, but I don't feel that means we should rule out adding in this basic functionality for the username/password system that I expect we'll support indefinitely. Thanks, Stephen
Stephen Frost wrote: > PAM is simply not always an option, unless you want to figure out a way > to use PAM modules without using /etc/passwd and company. Currently the > only way to use PAM w/ password-changing done in PG is to chown all the > various files and whatnot over to being owned by Postgres, which is a royal > pain and a very ugly mess. I suppose another option would be to > convince PG to run as root but that's not exactly an encouraged setup > either. > > That assumes that you are using system auth. PAM+LDAP for example has no such problems. cheers andrew
On Tue, 5 Dec 2006, Andrew Dunstan wrote: > > The second mechanism is the delay on authentication failure. The problem > > here is that a distributed application could attempt to brute force guess > > a password for a role. This could be fairly effective on a high speed LAN. > > So, the usual approach is to delay sending the failure message to the > > client for some period of time (specified in the patch by > > auth_failure_delay) to slow the progress of the password guesser. > > Naturally, environments where you cannot trust the local network sound > > like problem outside out scope. But, I see a lot of systems with sensitive > > company information (consider an HR system) which even employees should be > > denied access to. > > > > Arguably such systems should not be using standard password auth at all. > SSL with client certs is probably the way to go. Relying on password > strength checking and delay in such a case would be, to use David > Fetter's recent phrase, putting lipstick on the md5 pig. I agree with what they should do. However, what usually happens is that a senior employee wants to plug their tool (reporting, or what ever) into the database. Because we aren't supported like, say, Oracle is they have to connect via ODBC. What seems to happen then is, they're given a username and password. It's those accounts you have to worry about. > > Authentication failure delay can be done with PAM but not everyone will be > > abke to use PAM. > > > > Well, pam_cracklib will do an outstanding job on all these issues for you. > > > I'm not opposed to providing some of this stuff, although some does seem > to be reinventing the wheel. But we should be careful about how much > security we think we are really providing. Right, I think PAM does a great job but it isn't available on, say, Windows. Thanks, Gavin
On Tue, 5 Dec 2006, Tom Lane wrote: > Gavin Sherry <swm@linuxworld.com.au> writes: > > .... Instead, what we do is add up the different > > character types (lower, upper, digits, etc) and for each character type > > missing, we reduce the hypothetical password length: the theory being that > > the longer the password, the harder to guess. > > Where did you get this design for a password strength checker? > It doesn't sound like it has much to do with the algorithms commonly > used for such things. I'm not sure what's commonly done but I read it on some slides about PAM. I looked at what PAM does just now. It does do something close to what I did -- but with more configuration capabilities -- and checks for palindromes and similarity when changing a password. > > > Now, in the presence of encrypted passwords being sent across the wire, we > > can't do anything. So, we export the password strength tester to libpq. > > As already noted, that seems approximately useless. I figured it might be useful for applications like pgadmin which wanted to send the password encrypted on the wire but wanted to test of its strength. > > The second mechanism is the delay on authentication failure. The problem > > here is that a distributed application could attempt to brute force guess > > a password for a role. This could be fairly effective on a high speed LAN. > > So, the usual approach is to delay sending the failure message to the > > client for some period of time (specified in the patch by > > auth_failure_delay) to slow the progress of the password guesser. > > This is a waste of effort, unless you propose to put the delay into both > the success and failure paths, which hardly seems acceptable. Otherwise > a guesser need only abandon the connection attempt after X microseconds > and try another password. > That doesn't seem to be what PAM does, at leasts in the default config. What they do do is to sleep for a random period between no sleep and the threshold, so that the attacker cannot guess the appropriate time to wait before hanging up. Thanks, Gavin
Gavin Sherry <swm@linuxworld.com.au> writes: > On Tue, 5 Dec 2006, Tom Lane wrote: >> Gavin Sherry <swm@linuxworld.com.au> writes: >>> The second mechanism is the delay on authentication failure. >> This is a waste of effort, unless you propose to put the delay into both >> the success and failure paths, which hardly seems acceptable. Otherwise >> a guesser need only abandon the connection attempt after X microseconds >> and try another password. > That doesn't seem to be what PAM does, at leasts in the default config. > What they do do is to sleep for a random period between no sleep and the > threshold, so that the attacker cannot guess the appropriate time to wait > before hanging up. No, you missed my point: the attacker doesn't need to guess what the failure delay is. As long as he has a pretty good idea what the *success* response time ought to be, he can give up as soon as a bit more than that has elapsed. Yup, it's probabilistic because there's some uncertainty about the backend launch time, but what does he care? Brute-force password attacks are always probabilistic. A delay in the failure case is only helpful if you have some active way to prevent the attacker from making another try before the delay has elapsed. Which is something we don't have, at least not without introducing a lot more complexity/fragility into the postmaster than seems wise to me. regards, tom lane
On Fri, 8 Dec 2006, Tom Lane wrote: > Gavin Sherry <swm@linuxworld.com.au> writes: > > On Tue, 5 Dec 2006, Tom Lane wrote: > >> Gavin Sherry <swm@linuxworld.com.au> writes: > >>> The second mechanism is the delay on authentication failure. > > >> This is a waste of effort, unless you propose to put the delay into both > >> the success and failure paths, which hardly seems acceptable. Otherwise > >> a guesser need only abandon the connection attempt after X microseconds > >> and try another password. > > > That doesn't seem to be what PAM does, at leasts in the default config. > > What they do do is to sleep for a random period between no sleep and the > > threshold, so that the attacker cannot guess the appropriate time to wait > > before hanging up. > > No, you missed my point: the attacker doesn't need to guess what the > failure delay is. As long as he has a pretty good idea what the > *success* response time ought to be, he can give up as soon as a bit > more than that has elapsed. Yup, it's probabilistic because there's > some uncertainty about the backend launch time, but what does he > care? Brute-force password attacks are always probabilistic. I agree that your method makes sense but it's not what PAM seems to do. I'm no security expert though. The OpenSSH daemon /seems/ to do the same thing. Thinking about it, I'm comparing apples and oranges. The systems PAM is often being used for keep the connection open in the presence of an authentication failure. They assume a human is at the other end and made a typo. In our case, we basically terminate the connection. Hmmm :-(. > A delay in the failure case is only helpful if you have some active way > to prevent the attacker from making another try before the delay has > elapsed. Which is something we don't have, at least not without > introducing a lot more complexity/fragility into the postmaster than > seems wise to me. I agree. I had a think about what is involved there and as you say it would make the code a lot more complex. Thanks, Gavin