SQL Injection attacks against HL7 interfaces
Apr 9, 2014One of the questions that several people have asked me in the discussions triggered by the report of CDA vulnerabilities is whether there is any concern about SQL injection attacks in CDA usage, or other HL7 exchange protocols. The answer is both yes and no.
Healthcare Applications are subject to SQL injection attacks.
An SQL injection attack is always possible anywhere that a programmer takes input from a user, and constructs an SQL statement by appending it into a string, like this:
connection.sql = “select * from a-table where key = ‘“+value_user_entered+”’”;
There is any number of equivalents in programming languages, all variations on this theme. If the value the user entered includes the character ‘, then this will cause an error. It may also cause additional sql to run, as memorably captured in this XKCD cartoon:
[caption id=”” align=”alignnone” width=”666”] Exploits of a Mum[/caption]
There’s several ways to prevent SQL injection attacks:
- check (sanitise) the inputs so that SQL can’t be embedded in the string
- use parameterised SQL statements
- escape the SQL parameters (connection.sql = “select * from a-table where key = ‘“+sql_escape(value_user_entered)+”’”);
- ensure that the underlying db layer will only execute a single sql command
Doing all of these is best, and the last is the least reliable (cause it’s the easiest). Because all of these actions are not as convenient as the vulnerable approach, SQL injection attacks continue to be depressingly common. And that’s on web sites.
My experience is that healthcare interfaces tend to be written very differently to websites that are going to run in public. They are not written expecting hostile users - by and large, they don’t, either. And they are always written to a budget, based on estimates that don’t include any allowance for security concerns. That’s right - the only time I have seen security feature in interface costings is for the PCEHR.
So I assume that the default state is that healthcare interfaces are potentially subject to SQL injection attacks due to programmer efficiency (anyone who calls it ‘laziness’ is someone who’s never had to pay for programming to be done).
Healthcare Applications are not so subject to SQL injection attacks.
However, in practice, it turns out that it’s not quite such a concern as I just made it show. That’s for several reasons.
I was specifically asked about CDA documents and SQL injection. Well, CDA contents are rarely processed into databases. However the XDS headers that are used when CDA documents are exchanged are often processed into databases, and these are usually extracted from the CDA contents. So any XDS implementation is a concern. The PCEHR is an XDS implementation, though programmers never needed to wonder whether it sanitized it’s inputs. A side lesson from the PCEHR story is that name fields are not generally subject to SQL injection attacks, since it’s not too long before a name with an apostrophe trips them over if they are (and that’s true on more than just healthcare interfaces).
Really, the context where SQL Injection attacks are most likely is in the context of an HL7 v2 interface.
Some healthcare applications sanitize their inputs. But validation has it’s challenges.
However the real reason that healthcare applications are not so subject to SQL injection attacks is operational. An SQL injection attack is iterative. I think this is one of the best demonstrations of how to do one:
This an ASP.NET error and other frameworks have similar paradigms but the important thing is that the error message is disclosing information about the internal implementation, namely that there is no column called “x”. Why is this important? It’s fundamentally important because once you establish that an app is leaking SQL exceptions
The key thing here is that a general pre-requisite for enabling SQL injection attack is to leak interesting information in errors, and then the attacker can exploit that iteratively. Well, we’re safe there, because interfaces rarely return coherent errors ;-)
Actually, that’s not really true. It’s easy, if you can craft inputs to the interface, and capture outputs, to iterate, even if you don’t get good information. Mostly, typical users don’t get such access; they can enter exploit strings into an application, but the error messages they might generate downstream will go into some log somewhere.
That means that the interface error logs need protecting, as does access to the interfaces (in fact, this is the most common security approach for internal institutional interfaces - to restrict the IP addresses from which they can be connected to)
Generally, if you have access to the system logs and the interfaces, you’re very likely to have access to the databases anyway. Hence, SQL injection attacks aren’t such a problem.
But really, that’s pretty cold comfort, specially given that many attacks are made by insiders with time and existing access on their side. I’m sure that it’s only a matter of time till there’s a real world exploit from SQL injection.