> Let me caution you though: in most applications, if you concede to an attacker INSERT/UPDATE/SELECT (ie: if you have SQL Injection), even if you've locked down the rest of the database and minimized privileges, you're pretty much doomed.
I like how you qualified this with "in most applications." The huge mitigation factor would be if you restrict these heavily by user by using db users as application users, to enforce permissions. This has significant tradeoffs in a number of areas (particularly in scalability) but is very much worthwhile for internal business tools.
> Most teams we work with don't take the time to thoroughly lock down their databases, and we don't blame them; it's much more important to be sure you don't give an attacker any control of the database to begin with.
Well, beyond that, locking down the database is a lot of work. I am not sure of two presuppositions in your position though, namely:
1. That it is possible to fully lock down a database. There are tradeoffs that have to be made somewhere or shortcuts that get made, or new attack vectors that might develop over time....
2. That it is possible to guarantee that one denies an attacker any control over the database to begin with. Even if you encapsulate the db behind stored procedures (which we do in LedgerSMB) you have the issue that down the road, someone adds a trigger which is vulnerable to SQL injection and even if your higher application levels are perfectly secure.
The long run approach I think is to see security as something a team should set the bar very high for, but will inherently always be a work in progress.
For example, one thing not covered in this article is what happens when you run a function as security definer, as a superuser. This means that the function may do things that may fire triggers, and now those triggers also run as superuser, so eventually you get to a point where something in the pipeline is vulnerable. Fully locking down the database means, generally, that superuser security definer functions probably should not read/write rows, but that security definer functions that do read/write rows (i.e. non-system operations) should probably be assigned to nonsuperuser owners.