[MXS-191] Use canonical form to translate SQL to prepare statement Created: 2015-06-12 Updated: 2016-10-10 Resolved: 2016-10-10 |
|
| Status: | Closed |
| Project: | MariaDB MaxScale |
| Component/s: | N/A |
| Affects Version/s: | None |
| Fix Version/s: | N/A |
| Type: | New Feature | Priority: | Major |
| Reporter: | VAROQUI Stephane | Assignee: | Unassigned |
| Resolution: | Done | Votes: | 1 |
| Labels: | None | ||
| Description |
|
That a great security feature to avoid sql injection without modify application code |
| Comments |
| Comment by Steven Snelgrove [ 2016-09-02 ] |
|
Just guessing but the problem seems to be the intermediate representation produced by the SQL parser inside the database. The programmer developed the application with one tree in mind and the injected input results in another tree. Suppose that the intermediate representation had a serialization function which would produce a string and the string could then be hashed in some cryptographic manner. The resulting token would represent the shape of the tree. The application developer could build the application and once the database access is working, request a shape token from the database. This token would then be coded into the application and accompany the SQL requests in normal operation. The database would then parse the application's SQL requests. If after parsing, the shape of the generated intermediate representation did not match the programmer supplied shape token, the request could be failed. |
| Comment by Steven Snelgrove [ 2016-09-07 ] |
|
The previous comment has an idea that could prevent SQL Injection altogether. But it does require modification to a lot of interfaces. If the requirement were to just detect SQL Injection, then there might be a simpler way to do it. In a similar manner to the above, after parsing, walk the parse tree and produce a hash representing the shape of the parse tree. For each database user, keep a table of parse tree hashes with a count of how many times the hash has been seen. Any time a new hash is seen, trigger an alert. The idea behind this is that database applications would tend to do the same kinds of things over and over again. Absolutely unique queries should tend to be rare and might be the result of SQL Injection. The alerting should be optional and should depend on user role as a DBA would tend to generate strange queries. |
| Comment by Steven Snelgrove [ 2016-09-07 ] |
|
I suppose that you could get back to preventing SQL Injection if the start-up problem could be avoided. In other words, how to avoid failing the first instances of valid queries. Assume the implementation of comment 2 above. Also assume there were an interface that allowed the application developer to pre-load a set of known good hashes. Then the new-hash action could be set to fail the query prior to execution of the suspected parse tree. Or maybe you start the application with new-hash-fail disabled. You then run the qualification tests which should have exercised all possible queries. Then new-hash-fail is enabled. In this way, only unexpected queries would be failed. |
| Comment by Steven Snelgrove [ 2016-09-19 ] |
|
Here is a paper on preventing SQL Injection that expresses something quite similar to the ideas presented above. There are many papers about using parse trees to identify SQL Injection. However most of these then try to duplicate the parsing on the client side prior to sending the SQL string to the server. But the authoritative parser is the one on the server. So any client-side attempts to fix the problem are at best inefficient, and in the worst case, either wrong or not complete. The prevention of SQL Injection needs to be performed at the server. |
| Comment by Steven Snelgrove [ 2016-09-19 ] |
|
Another paper about preventing SQL Injection. This one is almost exactly the method described in the comments above. The difference is that it was coded as a client-side solution whereas the proposal above is to make SQL Injection Prevention a database server feature. |
| Comment by Christopher Tarquini [ 2016-09-21 ] |
|
Here's a relevant project that does this via an Audit plugin for MySQL: https://sourceforge.net/projects/mysqlauditids/ In his stackoverflow answer here he describes it working as you described: |
| Comment by Steven Snelgrove [ 2016-10-06 ] |
|
This idea is implemented in MySQL server Enterprise Edition. Confusingly, they call it a firewall. But it is essentially the ideas discussed above. http://mysqlserverteam.com/new-mysql-enterprise-firewall-prevent-sql-injection-attacks/ |
| Comment by markus makela [ 2016-10-07 ] |
|
In the upcoming 2.1 version of MaxScale there's the Gatekeeper module which aims to prevent SQL injection by storing the allowed query patterns and then matching incoming queries to it. As MaxScale already parses the query, there's no significant overhead to it. A similar approach could be used to convert the queries into prepared statements. |
| Comment by Steven Snelgrove [ 2016-10-07 ] |
|
I was explaining these ideas to my boss who is a really good penetration tester. He is the guy we always call on where injecting on updates, deletes, etc. Ha-ha. He quickly noticed a flaw in the argument. Unless comments are reflected in the hash, you can still inject. Most parsers drop comments at the lexical level. For this to work correctly, a comment marker would have to be propagated to the parse tree. |
| Comment by Steven Snelgrove [ 2016-10-07 ] |
|
Idea is already patented. http://www.google.com.uy/patents/US7487149 Publication number US7487149 B2 |
| Comment by markus makela [ 2016-10-10 ] |
|
Gatekeeper module implements a similar mechanism. |