Why is SQL Injection still a problem?

SQL Injection is probably the most popular attack vector for hackers when they attempt to break into databases.  The reason for this is that it is so easy for an attacker to gain access to the system, and typically to get pretty high level permissions to a database engine so that they can then export some of all of the data from the database engine.

The really sad thing about this is that it is very easy for software developers to protect against SQL Injection attacks.  The way that software developers protect the application from SQL Injection is by using parameterized queries instead of the older, and usually easier technique of simply building the database query using variables in the software code.

One of the reasons that I that I think that SQL Injection is just a big problem is thanks to the separation of duties that we have at most companies.  The reason that I say this is because the software developers that build the applications never have to deal with the cleanup from the SQL Injection attack.  Many developers, probably because they don’t work all that closely with database administrators, see SQL Injection as a SQL Server problem not an application problem.  This thinking would be wrong, as the only way to prevent SQL Injection problems is to protect the data at the application layer by using coding best practices like using parameterized queries like that shown below, taken from Chapter 8 of my book Securing SQL Server (this sample is for VB.NET, the book includes examples in C# as well as VB.NET).

Private Sub MySub()
Dim Connection As SqlConnection
Dim Results As DataSet
Dim SQLda As SqlDataAdapter
Dim SQLcmd As SqlCommand
SQLcmd = New SqlCommand
SQLcmd.CommandText = “sp_help_job”
SQLcmd.CommandType = CommandType.StoredProcedure
SQLcmd.Parameters.Add(“job_name”, SqlDbType.VarChar, 50)
SQLcmd.Parameters.Item(“job_name”).Value = “test”
Connection = New SqlConnection(“Data Source=localhost;Initial Catalog=msdb;Integrated Security=SSPI;”)
Using Connection
Connection.Open()
SQLcmd.Connection = Connection
SQLda = New SqlDataAdapter(SQLcmd)
Results = New DataSet()
SQLda.Fill(Results)
End Using
‘Do something with the results from the Results variable here.
SQLcmd.Dispose()
SQLda.Dispose()
Results.Dispose()
Connection.Close()
Connection.Dispose()
End Sub

Now I freely admin that coding the .NET code this way is harder than using Dynamic SQL which is shown below.

Private Sub MySub()
Dim Connection As SqlConnection
Dim Results As DataSet
Dim SQLda As SqlDataAdapter
Dim SQLcmd As SqlCommand
SQLcmd = New SqlCommand
SQLcmd.CommandText = “exec sp_help_job @job_name='” + MyVBNetVariableWithTheJobName + “‘”
SQLcmd.CommandType = CommandType.Text;
Connection = New SqlConnection(“Data Source=localhost;Initial Catalog=msdb;Integrated Security=SSPI;”)
Using Connection
Connection.Open()
SQLcmd.Connection = Connection
SQLda = New SqlDataAdapter(SQLcmd)
Results = New DataSet()
SQLda.Fill(Results)
End Using
‘Do something with the results from the Results variable here.
SQLcmd.Dispose()
SQLda.Dispose()
Results.Dispose()
Connection.Close()
Connection.Dispose()
End Sub

The problem that I have with application developers taking the easy, shorter way out is that their job isn’t to take the easy way out.  Their job is to build the application securing and robustly, not in such a way that the application is as easy as possible to write.  This problem can probably be traced back to the specifications which were written for the application which probably don’t mention security at all anywhere in the specification from the business unit.  Because security isn’t a primary concern for the business unit it is left as an afterthought, an afterthought which is typically ignored until after there has been a breech.

Another reason that I think that SQL Injection is a problem is that we trust that our users wouldn’t want to do anything to hurt our applications or their data as they have a vested interest in keeping the system working correctly.  And this is true to some extent.  However when you publish an application on the public Internet not only will you customers be using it, but others will be attempting to hit the forms within the application.  Because of this, we can’t trust any input that the application user passes in.  Even if the value that is passed in is from a hidden field, or has been validated by the front end. If the value hasn’t been validated by the back end, and properly scrubbed then it shouldn’t be trusted.  And the only way to fully validate and scrub the value is to use the parameterized query technique which I showed above, no other technique no matter how clever will be as successful.

I’ve been working in the IT space for about 15 years now, and I’ve worked on dozens of application development projects over the years at companies large and small, and I can’t recall a single application design specification which included security of the data as a component of the application development.  As the production DBA for companies I’ve forced the issue when I would find problems early enough in the development cycle, but often I wouldn’t find out about the application that was being built until it was time to deploy the application to production.  At this point it is to late to make the kinds of major changes which need to be made, and because security doesn’t add value to the application or to the business unit security isn’t given the developer or QA resources which are needed to make the changes needed to properly secure the data from potential attackers.

I urge everyone that reads this, developers and administrators alike, to look at how applications within your environment connection to the database engine (it doesn’t matter what database engine you use, they can all be broken into via SQL Injection, and yes MySQL is included in this) and if dynamic SQL is being used, and isn’t being properly parameterized talk to upper management about this problem.  Explain to them that while this won’t be something which adds features to the application and won’t necessarily add value to the business, this is something which absolutely needs to be resolved.

Suffering from a SQL Injection breach will have a negative impact on the company, and the IT department in several ways.  From the company side of things customers will loose confidence in the company, which means that they will stop purchasing your product or using your service.  This means that the company will make less money.

Internally the business unit will loose faith in the IT staff as they can’t properly secure their applications from attackers.  The business unit will then loose faith in the developers as the IT staff explains that the only way to protect 100% against this sort of attack is to fix the application which means lots of time (possibly hundreds or thousands of man hours) just fixing database access code and not adding functionally into the application.  The business unit will then assume that the developers aren’t good developers and may request that new developers be brought in, that the application development be outsourced, or that a third party application be purchased.  All of which mean that you and/or your coworkers could easily be out on the street looking for more work.

If you are working on a new development project and security isn’t included in the specification push to have it added.  Yes it will slow the delivery of the application down, but it will remove the risk of a data breach, or worse than that a total network breach (where the attacker is able to get into the company network and take control of internal resources like domain controllers, file servers, etc.) which would be a major disaster  to any company no matter how large or small.

I hope that you take this to heart and fix any applications in your environment which have SQL Injection issues so that we can all stop reading about these data breaches which are coming all to often.

Denny

Share

2 Responses

  1. I’m sorry to be blunt, but my blood boils every time I read about another successful SQL Injection attack.  As Mr. Denny correctly points out, there is no excuse.Personally, it’s laziness or incompetence.I’ve been in IT for over 40 years, and my early years were spent writing both application programs and operating system code (yes, we actually wrote our own back then instead of buying packages!)We solved the issues of Buffer Overflow in the 70’s, and we checked all input to application programs to insure the input was valid.It seems like everything we learned (the hard way) back in the 60s-70’s was forgotten in the rush to move from mainframes to servers.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Trust DCAC with your data

Your data systems may be treading water today, but are they prepared for the next phase of your business growth?