1

Right now, we might do something like password varchar(72), when defining a password column, with for example BCrypt. But there's a lot of folks that don't do this very effectively. Maybe they just put the plaintext, or a single unsalted md5 hash, or some other terrible strategy.

But virtually all these offenders still use databases. So why isn't this kind of functionality baked into databases? Something like mypass password('BCrypt:10'), and accessed like INSERT INTO people(name, mypass, other_data) VALUES(?, ?, ?) which would take the plaintext password from the user and pass it to the table. But the table would store the appropriate BCrypt hash value. Then, we could do something like SELECT other_data FROM people WHERE name = ? AND mypass = ? - this again would take the plaintext from the user logging in, but load the salt and perform the analysis to determine of the the password was a success or not.

When it comes to storing data, we go with databases instead of flat files or what have you because they're reliable, tested, and simple (in comparison to rolling our own). Since it's clear that in the wild there are innumerable where password storage is unreliable and untested, why is this sort of data storage not undertaken by the database itself?

corsiKa
  • 253
  • 1
  • 3
  • 10

4 Answers4

6

It would be possible but:

  • It's not standard SQL (it would have to become a feature, part of the product)
  • All processing power will be centralized on the database
  • Not all webapplications use SQL databases

You're just shifting the problem, 10 years ago it would have been acceptable to use MD5+salt. So your database would implement MD5+salt right? Alright 10 years later, you as a developer need to use password again hashing on database level, now the database supports bcrypt, but you still will use MD5+salt because it's what you know right?

Why does it still need to support MD5+salt you might ask? Simply because you are probably still using the same application. The migration to the new scheme will still require developer intevervention, it won't happen auto-magically.

Making it a feature to just use an automatic password hashing algorithm isn't possible because you will have implemented an older scheme for older applications. This would then require the database product to suddenly implement an auto-migration feature. This is complex to implement.

So you can see, the problem shifts from it being a developer issue to a database developer issue.

Lucas Kauffman
  • 54,229
  • 17
  • 113
  • 196
  • * Naturally, it would need to be standardized. Many things get standardized. * Processing power has to come from somewhere. If your database was so close to being over the top that this pushes it over, it was going to happen soon anyway. * No, not all. But a whole heck of a lot of them do. * Yes, but the same could be said for file storage in a database instead of the file system. We're shifting the problem to something seamless to the user. – corsiKa Jun 26 '14 at 21:04
  • I'll update my answer – Lucas Kauffman Jun 26 '14 at 21:07
  • The only serious issue I can see is point 2 where you would be using processing power on a dedicate db server rather than on your web server. I still don't see this as a show-stopper. Edit: I always speak too fast. Another issue is that you'd be carrying passwords around from your Web server to your db server, this might be an issue for you if the Web server is ok but not the db one. – Steve Dodier-Lazaro Jun 26 '14 at 21:12
  • When it comes to migrating passwords, actually having the db handle this would dramatically simplify migrations. If you have a field that is still md5'd, next time the user successfully reconnects you can update it to bcrypt from within the db. – Steve Dodier-Lazaro Jun 26 '14 at 21:13
  • I had considered the problem of updating, and I don't think it would be a big problem, really. You could simply `ALTER` the column to support a new scheme, say `BCrypt:12` after you feel that 10 is too low, or `SCrypt` because a flaw was found in BCrypt or something. After a period of transition to let users who log in against the old hash get their new hash in the database, you remove the old hash from being allowed; other users will have to perform a password reset. – corsiKa Jun 26 '14 at 21:14
  • 1
    No that's the wrong way to do it. You should never do it that way. The only correct way to migrate password is keeping a boolean value next to the password to see if it has been updated or not. All passwords should immediately be re-hashed using the other algorithm so scrypt(bcrypt(password)). Otherwise you might keep the old passwords around for 10 years. After a user logs in the password can then be changed again to just use scrypt(password) and the boolean can be set so you know you can just use scrypt instead of scrypt(bcrypt(password)) – Lucas Kauffman Jun 26 '14 at 21:16
  • You must not have read the last sentence that said you remove the old hash after a transition period, forcing users who didn't transition to do a password reset. You know, the same kind of problem you have performing this kind of switch when it's managed by an application instead of the database. – corsiKa Jun 26 '14 at 21:19
  • Just for the sake of arguing, in most legal systems you are required to delete customer data within 1 or 2 years of them not using the service any more, so if you're keeping an unused account for 10 years you're probably doing something illegal. :) – Steve Dodier-Lazaro Jun 26 '14 at 21:19
  • @corsiKa your scheme means legacy users won't be able to log in anymore, my scheme effectively secures the hash and still allows for users to log in, even after 5 years. – Lucas Kauffman Jun 26 '14 at 21:21
  • @SteveDL That would require you to be a "customer" in the first place ;). Whatabout Facebook? Gmail? Linkedin? I also highly doubt that china has such good protection laws and they account for close 1/6th of the people on earth. – Lucas Kauffman Jun 26 '14 at 21:24
  • 2
    Anyway if we want to discuss things let's take it to the chatroom as this is getting a bit out of control :) – Lucas Kauffman Jun 26 '14 at 21:25
  • In your scheme, if I went from bcrypt10(password) to bcrypt15(bcrypt10(password)) to scrypt(bcrypt15(bcrypt10(password))) and I had someone who logged in last on bcrypt10 (the 5 years guy) and another who last logged in on bcrypt15 (the last week guy) then a boolean value isn't sufficient. But I agree that it's an implementation detail that is only a minor part of the larger overarching question and would be better served in chat. – corsiKa Jun 26 '14 at 21:26
  • Like I said take it to the chatroom :) – Lucas Kauffman Jun 26 '14 at 21:27
2

There's several reasons:

  • You'd need to modify the query planner to understand the column types, as you'd have to select the username, read the salt, and then handle the password hash.
  • You're adding additional load to the database, which is often the hot spot in applications, for work that can just as easily be done in the application.
  • You'd need a way to upgrade hash types -- so is that a database schema modification?

If someone doesn't know how to write an application, giving them a "magic" database column isn't going to fix the problem.

David
  • 15,939
  • 3
  • 50
  • 73
  • Naturally, the query planner needs to be adapted for this, but it probably wouldn't be a showstopper. Additional load can be a problem, but there's already all kinds of functions that go on in the database that could be done in the application, too. I see that as an edge case (where the load is the straw that breaks the camel's back). And upgrading hash types would be pretty simple - you just add an additional supported type, and remove the old type after a transition period - similar to what is done *manually* now. – corsiKa Jun 26 '14 at 21:17
  • to be honnest, who cares about generating their own salts these days, most implementations of bcrypt, scrypt or pbkdf2 will generate a string which states $3$HASH$SALT. It's a lot easier and avoids developers from having to break their head on how to implement it (often they end up like good old dave (http://security.stackexchange.com/questions/25585/is-my-developers-home-brew-password-security-right-or-wrong-and-why) – Lucas Kauffman Jun 26 '14 at 21:20
  • but +1 because you are entirely correct that it's just shifting the problem. – Lucas Kauffman Jun 26 '14 at 21:34
1

Nice question! Very honestly my take is "because nobody did it". There probably isn't much of a market for it in the eyes of database developers since the website developers who are not stupid already have their own code.

This being said, it's a very good idea to place security code (sanitisation, secret storage, declassification...) in ready-made libraries rather than on the client side because it means there is now one place where it needs to be done properly instead of tens of thousands; so long of course as your database library is transparent about how passwords are being salted and hashed and offers reasonable defaults and customisation options to developers.

Editing after seeing others' answers: doing so within the DB server itself could cause more performance issues than on the front-end side because DB's are less scalable than front-ends; it also means that you keep the "boiling potato" longer since your clear-text password travels around from your front-end server to your database.

However, I still don't see how a client library to a database couldn't receive a password as a data type and convert it into something hashed and salted itself. It would still need some form of cleartext password cache to automatically handle hash function updates though (but that'd have been the case anyway in the same front-end process that would run the library's code).

Steve Dodier-Lazaro
  • 6,828
  • 29
  • 45
1

People do all kinds of stupid things. That doesn't mean we should take everything that might go wrong in the application and delegate it to the database system.

The job of a database system is to manage data. Of course modern systems have all kinds of additional features which blur the line between application and database. But expecting them to handle the user authentication of your website seems a bit over the top. That's the job of the application.

Passing the plaintext password to the database system also has implications for security: You now have to make sure that the password doesn't turn up in the query log or get intercepted on the way from the webserver to the database system (unless they're on the same machine).

Fleche
  • 4,024
  • 1
  • 17
  • 20
  • I can see the point about security implications, but those seem like implementation details. They aren't conceptual road blockers. – corsiKa Jun 26 '14 at 21:28
  • The conceptual issue is that this bloats the database system and burdens it with tasks it was never meant for. The database system isn't a nanny for application developers. – Fleche Jun 26 '14 at 21:40