There is no general fix for SQLi because there is no fix for human stupidity. There are established techniques which are easy to use and which fix the problems (especially parameter binding) but one still has to use these techniques. And many developers are simply not aware of security problems. Most care that the application works at all and don’t care much about security, especially if it makes things (even slightly) more complex and comes with additional costs like testing.
This kind of problem is not restricted to SQLi but you’ll find it with buffer overflows, certificate checking, XSS, CSRF… . It is more expensive to do secure programming because of the additional testing and of the additional expertise needed by the (thus more expensive) developer. And as long as the market prefers it cheap and does not care much about security you get the cheap and insecure solutions. And while security by design helps a lot to make it better developers often work around this design because they don’t understand it and it is just in their way.
Because it’s not a problem.
When was the last time a company with a SQL injection vulnerability got hauled up in court, and slapped with a big fine for being reckless with user data, and the directors’ warned, fined or locked up for negligence?
When was the last time a company lost a big contract because their company website login page didn’t validate passwords properly?
When was the last time a qualified regulator/auditor from a professional organisation had to approve and sign off a public facing computer system before it could be put into use?
You would think that “people will die” would be a good enough reason to make buildings with fireproof materials, alarms and good escape routes. It wasn’t. We introduced regulation to force non-flammable building materials, fire safe designs with fire breaks, fire alarms.
You might think “people will die” would be a good enough reason to make everyone care about building structural design. It isn’t. It just isn’t. We have to have regulation to have qualified engineers sign off on building designs, that they be designed and built for specific uses, and when things fail, society takes the engineers to court.
You would think that “people will die” would be a good enough reason to make food processing clean and safe, but it wasn’t.
SQL Injection is less obvious, less publicly visible, and has less severity impact, and is in a completely unregulated industry.
Even to companies which do care about it, they can’t usefully advertise “No known SQL injection vulnerabilities in our code” as a marketing bullet point anyone cares about. It’s not the sort of question customers ask salespeople. It’s not a competitive advantage for them, it’s a cost, an overhead. Protecting against it makes them less competitive, slower moving, doing more work for the same functionality.
The incentives are all aligned for it to keep existing. So it keeps existing.
Make SQL injection a problem for companies, and they will make it go away.
SQL injection is still around because the software world still doesn’t understand that programmatic generation of tree-structured values (like queries or markup) should be done by constructing syntax trees as first-class objects, not by concatenating strings that represent fragments of a language.
There has been a bit of progress in recent years with the increasing availability of query builder tools like LINQ to SQL or SQLAlchemy, but that’s on the programming language side. Relational databases still don’t offer a standard, compelling alternative interface that’s not fundamentally based on sending queries as strings.
Prepared statements with query parameters are barely an improvement, because they’re only easy to use if the structure of your queries—which tables are joined, what filtering conditions, what columns to project—is fixed. When you have an application that needs to construct query text at runtime, prepared query parameters are a big pain to use.
So if a standardized, non-textual, tree-structured protocol could be constructed for describing and communicating queries to the database, and it was designed to be easier to use than textual queries, then that would solve the problem in the long term. But the problem won’t go away until the industry adopts something where the path of least resistance is safe. As long as we insist on unsafe-by-default systems where writing safe code takes unnecessary effort, problems will be with us. (Think of all the buffer overflows that don’t exist at all in memory-managed languages!)
innerHTML property to set it to HTML text that’s built by naïve string concatenation. A lot of XSS vulnerabilities would never have existed if the
innerHTML property had never been put into the browsers’ DOM implementations.
Also, for folks who haven’t seen Tony Hoare’s talk on null pointers, it’s simultaneously orthogonal (null pointers, not SQL injection) but at the same time incredibly relevant:
- Tony Hoare, “Null References: The Billion Dollar Mistake”.