|
Condition 1: Running Dynamic SQL Generated with Unsanitized Texts
OK, everyone knows this. The programmer takes an argument from a web page submission and plugs it into SQL as part of preparing a database interaction. Here’s a sample in Java:String loginSQL = "SELECT USER_NAME, AVATAR_IMAGE, LAST_POST_TITLE, LAST_POST_TIME FROM USER_INFO WHERE USER_ID IN (SELECT USER_ID FROM USER_PASSWORD WHERE USER_EMAIL = '" + parm (USER_EMAIL_PARM) + "' AND HASH_PASSWORD = PASS_HASH_FUNCTION (1, '3315', 'passHash1', '" + parm [USER_PASSWORD_PARM] + "')";This example is simplified to some degree, but the effect is the same. If an attacker enters a password like this Oracle example:
LOL' UNION ALL SELECT CURRENT_USER, NULL, PRIVILEGE, SYSDATE FROM SESSION_PRIVILEGES -- ' ;…then the attacker may well get the identity of the current database user and a list of all privileges active for that user.
The discussion is not over.
I saw a StackOverflow discussion on dynamic SQL devolve into a nasty, frothy argument against it because some thought any dynamic SQL, anywhere, always constitutes a SQL Injection vector. Others said it’s only a vector when poorly coded. Neither is really correct, because this is not the only condition needed for an injection vulnerability.Condition 2: Application Connects as Admin-Level Database User
Most web applications and web frameworks follow what Oracle calls the “One Big Database User” model. Such an application connects to the database as the owner of the tables it uses. I’m a database guy. I recognize this as both risky and unnecessary. However, simply identifying this as an intentional developer choice makes me recall a lot of unpleasant conversations I’ve had with developers. 'What, hey, ho? Creating and selecting a specific user account for an application, other than the table owner?' This is effectively inconceivable for many application developers. 'What else are we supposed to do?' The social dysfunction and gappy reasoning around this assumption could fill volumes. So the application connects as the owner of the application tables — what’s wrong with that? What’s wrong is that the application owner has the privilege of dropping any object it owns. It can do a lot of destruction not intended by the application as end-user functionality. The real question is this: Why do we configure an application with database privileges we know we never want its users to have? The application programmer knows that his/her intended ordinary end user should not be dropping tables or creating triggers or experimenting with constraints. (As an aside, SQLFiddle’s intended end user is expected to do these things.) The database owner may also be granted some extremely powerful privileges - adding or dropping disk storage, creating end users, querying system information. Usually these needs go away after installation. The end user should not have them. For anything not intended as a programming platform, the application does not ever have to connect as the table owner. Period. The application needs to connect as a separate end user with only the privileges needed to work those specific operations needed for the application. When the application connects with escalated privileges, the ability to run SQL distorted by an injection attack makes that distorted SQL all the more dangerous. If you limit the attacker by restricting the application’s database account, you’ve already mitigated the damage (and possibly eliminated it.)Alternative approach, or, why doesn’t SQL Fiddle fall apart?
SQLFiddle is a utility site that allows you to run SQL on a mystery cloud database about which all you know is that it acts like (and presumably is) whichever database type you chose: Oracle 11gR2, MySQL 5.6.6, PostgreSQL 9.3.1 or others. Here is an example for Oracle: