7

(Okay, so I'll confess upfront that while I'm trying to educate myself the current state of my knowledge on web applications security is still pretty shallow. So I appreciate your patience if the way I ask this is a little clumsy.)

I was catching up on out some infosec news a few days ago when I came across this item about a gray hat security researcher/hacker who was arrested earlier this month on charges related to breaking into the web site of a county elections body in Florida. From a technical standpoint, it appears that compromise occurred when this fellow used an SQL injection attack against a login database and managed to steal the plaintext (!) password of a county elections supervisor from it. He then used those credentials to login to the content management system of the website, and that was that.

After reading about this something odd struck me. I realized that there was a pretty fundamental point about the nature of these ultra-common SQL injection thefts from password databases that I really didn't/don't understand at all. That being: Why is it even possible to manipulate a login database to disclose password hashes (and/or usernames, salts, or any other authentication-related info) in the first place?

I can understand why SQL injection can work against databases in general; the archetypal common job of a database is to return user-readable information stored in it in response to a user query. But the job of a login credential database is very different. It does not actually require sending stored authentication information outside the database, but instead just providing an answer to the web server passing along the user-supplied credentials about whether they are valid or not. (Right?)

So why do we even use full-power database software and SQL queries to handle the pretty limited needs of username & password authentication at all?. Why aren't there limited-purpose database applications specifically aimed at just doing what a password database needs to do, vs. using general-purpose applications that leave lots of room for SQL injection to occur? What am I missing?

  • 1
    BTW, obviously the password database should have only contained password hashes created by a robust and "slow" cryptographic hashing algorithm and using unique-per-user salts. And certainly NOT,under any circumstances, plaintext passwords But in the interests of defense-in-depth let's set that aside here and focus on why password databases are even capable of divulging passwords or password hashes to begin with. – mostlyinformed May 20 '16 at 8:23
  • 1
    It's possible because the developer was obviously lazy, and/or incompetent. – user1751825 May 20 '16 at 10:50
  • 1
    No modern system should allow SQL injection. It's easy to avoid simply by using only parameterized queries. – user1751825 May 20 '16 at 10:51
8

There's a big gap between "does not require" and "implemented by the lowest bidder".

why do we even use full-power database software and SQL queries

Because if you're already running a SQL database for your transactional data, implementing a second technology stack with appropriately trained development and support staff for a very specific function is very expensive.

Given they can't get one appliction stack right, how are they going to cope with two?

Admittedly the problem of SQL injection arises from APIs which don't separate code (SQL) from data (parameters) while there are other database systems (and SQL APIs) which do enforce this separation. But relational databases and SQL databases in particular, provide a huge amount of functionality which is simply not available in the other types of databases. It would be very difficult to write a shopping cart which uses LDAP for persistence.

IMHO the people responsible for developing this system are just as culpable as the hacker.

  • I have some addition: the people who developed a shit-code are semi-culpable, the main guilt here is at the person who signed an implementaion "done" and in production. The responsibility of checking what you're actually doing exists everywhere, IMHO – Alexey Vesnin May 20 '16 at 8:45
  • "Given they can't get one appliction stack right, how are they going to cope with two?" A very fair point. I suppose one could try to design a solution that was (relative to most types of server software) more "idiot-proof" than maintaining a standard database. Or put more technically, "secure by default" rather than "insecure by default" like the current way. But I take your point. – mostlyinformed May 26 '16 at 6:51
2

Another angle to symcbean's answer.

The whole situation seems rather simplified. Who should take care of what can be queried and what can't? The underliyng DB (using special tables for user storage), the backend of the web application server or even a WAF? What about queries including LIKE statements (i.e. PasswordHash like 'a%', you can see where this is going)? If we go further, SQL injection isn't just about stealing login credentials. There might be a ton of more sensitive information that can be extracted. Even worse, it can lead to RCE on the DB server. And so on and on.

Seems easier to just implement measures to prevent SQL injection (by this I of course talk not just about parametrizing SQL statements, but about the whole defense-in-depth approach to prevent SQL injection).

2

usually a user table provides the relational association to content in the actual database.

eg user:jon_smith posted this blog post

The user table is also the logical place to store login credentials. The problem/question is not 'why is a database storing login credentials', but rather 'why arent people storing hashed values of passwords and comparing the hashed value to authenticate.

The simple answer is bad/lazy developers and cheap product managers who rather pay £500 for a student or freelancer to build a database for an election compared to a professional software developer

1

So why do we even use full-power database software and SQL queries to handle the pretty limited needs of username & password authentication at all?. Why aren't there limited-purpose database applications specifically aimed at just doing what a password database needs to do, vs. using general-purpose applications that leave lots of room for SQL injection to occur? What am I missing?

What you're missing is that databases are general tools designed for widespread use cases. What you're describing is a very specific tool, designed for a very specific use case.

The question comes down to one of maintenance and cost. It's generally cheaper and easier to use common tools than rely on something more specific like you're describing.

Properly used, a database is perfectly fine to store data in and query it directly from the program. I don't personally know of any solutions like you're describing in widespread use. That doesn't mean they don't exist, but it'd imply they aren't terribly common.

Also, it comes down to security design. What you're describing is a secure design. If the website in question wasn't designed with security in mind, it's not going to include secure features like you describe.

The point being, security doesn't (generally) just come out of the box. The default is normally no security. If it's not actively designed in and thought about, you're not going to get it. That's one of the biggest problems we face that security must be thought of from the start, not as an afterthought.

  • "What you're missing is that databases are general tools designed for widespread use cases. What you're describing is a very specific tool, designed for a very specific use case." Well, that's true, certainly. But don't we already have very purpose-specific security tech in common use for key things? The example that comes immediately to mind is a TPM, which is basically a low-capability SoC that is designed to do one or a few security-critical things with high assurance. (Still, definitely food for thought.) – mostlyinformed May 26 '16 at 7:03
  • 1
    @halfinformed purpose specific solutions are just that. Purpose specific. TPM is limited to protecting hardware. It doesn't really help you for much of anything else. Getting more specfic however, I'd say that adding a piece of technology involves making a decision whether you want to support that or not and if it's worth the cost. Some kind of component with "compare only" access is certainly more secure, but is it worth the added maintenance costs? Also, the people who store passwords in the clear clearly don't care about security. They won't even do the standard solution. – Steve Sether May 26 '16 at 20:19
  • I would certainly agree that any limited purpose solution has to bring more benefits to a system than costs, including on-going maintenance costs, in order to be appropriate. On the other hand, in my view a limited purpose solution that is designed to be more "secure by default" can--sometimes--have lower upfront setup & configuration costs, as well as lower ongoing configuration management & vulnerability management costs. (Because there are many fewer capabilities to setup/monitor, and less attack surface to maintain.) But certainly it's always a cost/benefit judgment call. – mostlyinformed May 28 '16 at 18:45
  • @halfinformed I'd completely agree. At the moment, I don't know of any solutions as you described that are cheap, well maintained, and time tested. But if there were, it'd be an attractive solution. – Steve Sether May 28 '16 at 20:18
1

Adding more tech to the stack isn't a very efficient of cost effective way to handle this, and generally, storing authentication data in the database isn't an issue. It's more of how you store it and how it can be accessed.

This moves us on to your other question about SQL injections. They're easy to prevent, and I venture that most sites that haven't are a result of lazy programming and/or lazy database design (don't store passwords in plain text!). I don't mean that to sound insulting to anyone, but it really boils down to the language or method being used to get to the database and how it's implemented.

For instance, PHP used to have mysql commands, that then became mysqli and now it's encouraged to use PDO for situations to address this problem. The reason that progression occurred is to ensure that whatever input is provided to the server is presented in a valid format.

One other thing that caught my eye here is that you mentioned databases are meant to return user-readable information. That's one of many uses, but is not exclusive to a database's purpose. The problem isn't the database, it's how you get to it. There are many cases where you'll want/need to be able to send commands to a database for very valid reasons.

SQL injections work on input and whether or not that input is validated prior to requesting information from the server. So, the problem isn't the database, it's the process of requesting information from it. You can, of course, store credentials in other formats and some do, but these tend to have limited flexibility.

Also, keep in mind that a SQL injection is but one of many attack vectors to be concerned with. It just gets a lot of press because it's about the easiest way to get into an improperly configured system.

0

A database is not an authentication tool. If you already used an authentication tool (the website login shared credentials with computer or application login elsewhere, for instance a web version of your company finance app) then by all means use Active Directory, PAM or RADIUS or whatever for both.

Running a second, isolated, database just for your web app's user login alongside the massive database that holds the rest of their details, plus maintaining the authentication intermediary, creates more problems, and ultimately that database still exists and may be breached in many other ways. If they made a mistake to allow SQL injection, they'd probably make enough other mistakes that would expose the 'special' database directly or through their homebrew authentication processor.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.