I’ve been teaching a lot more about SQL Injection lately (including blog posts). I’ve been doing this because, despite this being a 21 year-old problem with well defined solutions, we’re still dealing with it. Recently, while sitting in the speaker room at Techorama Netherlands (fantastic event, strongly recommended), I had the opportunity to spend a little time with Niko Neugebauer. I was freaking out because my demos were failing (fixed ’em finally). Niko was talking to me about the new Feature Restrictions and their effect on SQL Injection in SQL Server 2019. I didn’t know what he was talking about, so I had to look it up. Of course, top resource, Niko’s blog.
Feature Restrictions in SQL Server 2019
The Feature Restrictions in SQL Server 2019 are actually being added there from Azure SQL Database, where they already exist (Azure first, for so much). Microsoft has some documentation on the Feature Restrictions available here. Beyond that, and Niko’s blog, there isn’t much available on the internet yet (one exception, more on that in a minute).
The concept is simple. A new command has been created:
With this you can disable, or re-enable, two different behaviors:
User information in error messages
Why these two? Let’s take a minute and talk about SQL Injection.
SQL Injection Attacks
Traditionally, this is where a link to the XKCD cartoon of “Little Bobby Tables” should be. I’m going to let you look it up if you don’t know about it.
Instead, let’s talk about some of the common vectors of SQL Injection. Obviously, building and executing strings is the biggest issue. Appropriate use of parameters will do more to the fix the problem than almost any other step. However, it’s also enhanced by bad code on the front-end which doesn’t appropriately clean the data, inappropriate error handling, bad security, bad data isolation, and more.
The keys to the attack are to get back a few bits of information, usually in error messages in the case of a normal attack, or, through the use of the WAITFOR command in a blind attack (for more detail, I’m talking about this stuff at the PASS Summit). Getting error messages with information about the database makes it easier for me to hack your system (if I was evil). Knowing that I have a SQL Injection vector through the WAITFOR command helps me target appropriate systems (if I was evil).
So, what has Microsoft given us in the Feature Restrictions in SQL Server 2019?
Mitigation From the Feature Restrictions in SQL Server 2019
Thanks to the addition of these Feature Restrictions, we have the ability to better control some aspects of error handling directly from the database. Further, since most of us will never, ever, have a use for WAITFOR in production code, we can turn that bit off.
Therefore, with the inclusion of these two Feature Restrictions in SQL Server 2019, we get some SQL Injection mitigation.
However, it’s only mitigation, and not much of that.
I really dislike SQL Injection fairly intensely. It’s such a well known problem with a whole bunch of easily implemented fixes. There really are no longer excuses for anyone, let alone major corporations with sophisticated IT departments, to be suffering from SQL Injection attacks in this day and age.
Therefore, anything that helps fix this, helps fix this. However, if you go and read this blog post by Solomon Rutzky, you’re going to find two things. First, someone who dislikes SQL Injection possibly more than I do. Second, a whole list of issues around just how mild, almost to the point of uselessness, the level of mitigation offered by the Feature Restrictions in SQL Server 2019 are.
There are two things that you absolutely must do to address SQL Injection: Parameterize your queries and clean your inputs. However, let’s face it. With all the code out there that is building and executing dynamic T-SQL, the chances of this happening are near zero. Therefore, some degree of mitigation is vital. Therefore, as much as I agree with Solomon on just how little this helps, I’m going to say that the Feature Restrictions in SQL Server 2019 are a good thing. Why? Because even a little bit of help is better than no help at all.
We should be screaming from the rooftops to fix the bloody code and architectures that have landed us in this fix. However, also asking for more of these kinds of mitigations from Microsoft and other vendors, may ultimately lead to at least radically reducing the problem.