Home » SQL injection is 17 years old. Why is it still around?

SQL injection is 17 years old. Why is it still around?


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.

[Edit: But there’s an EU regulation that websites have to warn you if they use cookies. And they do. So regulating public facing computer systems to make them more annoying can come into effect – even if the current regulation is pretty useless.]

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!)

Note that the same fundamental problem as SQL injection plagues the Web, under the name of cross-site scripting—which is really just Javascript injection into dynamic HTML pages. A very common pattern is Javascript programmers who, instead of working with the DOM by treating it as a tree of objects, resort to the 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”.

Related Solutions

How can I use environment variables in Nginx.conf

From the official Nginx docker file: Using environment variables in nginx configuration: Out-of-the-box, Nginx doesn't support using environment variables inside most configuration blocks. But envsubst may be used as a workaround if you need to generate your...

Difference between .bashrc and .bash_profile

Traditionally, when you log into a Unix system, the system would start one program for you. That program is a shell, i.e., a program designed to start other programs. It's a command line shell: you start another program by typing its name. The default shell, a...

Custom query with Castle ActiveRecord

In this case what you want is HqlBasedQuery. Your query will be a projection, so what you'll get back will be an ArrayList of tuples containing the results (the content of each element of the ArrayList will depend on the query, but for more than one value will...

What is the “You have new mail” message in Linux/UNIX?

Where is this mail? It's likely to be in the spool file: /var/mail/$USER or /var/spool/mail/$USER are the most common locations on Linux and BSD. (Other locations are possible – check if $MAIL is set – but by default, the system only informs you about...

How can I find the implementations of Linux kernel system calls?

System calls aren't handled like regular function calls. It takes special code to make the transition from user space to kernel space, basically a bit of inline assembly code injected into your program at the call site. The kernel side code that "catches" the...

Is a composite index also good for queries on the first field?

It certainly is. We discussed that in great detail under this related question: Working of indexes in PostgreSQL Space is allocated in multiples of MAXALIGN, which is typically 8 bytes on a 64-bit OS or (much less common) 4 bytes on a 32-bit OS. If you are not...

Explaining computational complexity theory

Hoooo, doctoral comp flashback. Okay, here goes. We start with the idea of a decision problem, a problem for which an algorithm can always answer "yes" or "no." We also need the idea of two models of computer (Turing machine, really): deterministic and...

Building a multi-level menu for umbraco

First off, no need pass the a parent parameter around. The context will transport this information. Here is the XSL stylesheet that should solve your problem: <!-- update this variable on how deep your menu should be --> <xsl:variable...

How to generate a random string?

My favorite way to do it is by using /dev/urandom together with tr to delete unwanted characters. For instance, to get only digits and letters: tr -dc A-Za-z0-9 </dev/urandom | head -c 13 ; echo '' Alternatively, to include more characters from the OWASP...

How to copy a file from a remote server to a local machine?

The syntax for scp is: If you are on the computer from which you want to send file to a remote computer: scp /file/to/send username@remote:/where/to/put Here the remote can be a FQDN or an IP address. On the other hand if you are on the computer wanting to...

What is the difference between curl and wget?

The main differences are: wget's major strong side compared to curl is its ability to download recursively. wget is command line only. There's no lib or anything, but curl's features are powered by libcurl. curl supports FTP, FTPS, HTTP, HTTPS, SCP, SFTP, TFTP,...

Using ‘sed’ to find and replace [duplicate]

sed is the stream editor, in that you can use | (pipe) to send standard streams (STDIN and STDOUT specifically) through sed and alter them programmatically on the fly, making it a handy tool in the Unix philosophy tradition; but can edit files directly, too,...

How do I loop through only directories in bash?

You can specify a slash at the end to match only directories: for d in */ ; do echo "$d" done If you want to exclude symlinks, use a test to continue the loop if the current entry is a link. You need to remove the trailing slash from the name in order for -L to...

How to clear journalctl

The self maintenance method is to vacuum the logs by size or time. Retain only the past two days: journalctl --vacuum-time=2d Retain only the past 500 MB: journalctl --vacuum-size=500M man journalctl for more information. You don't typically clear the journal...

How can I run a command which will survive terminal close?

One of the following 2 should work: $ nohup redshift & or $ redshift & $ disown See the following for a bit more information on how this works: man nohup help disown Difference between nohup, disown and & (be sure to read the comments too) If your...