views:

580

answers:

2

For a web application, when creating the user which will connect to the MySQL database, you have the choice of privileges. Assuming that the only actions intended to be done by that user are SELECT/INSERT/UPDATE/DELETE, it seems to make sense to only provide those privileges, however I've never seen that recommended anywhere - what are the reasons for and against this method?

+2  A: 

There are other privileges that a user might need during an ordinary application, for example:

  • CREATE TEMPORARY TABLE
  • EXECUTE (stored procedures)
  • FILE (for SELECT INTO and LOAD DATA)
  • LOCK TABLES

There's also the possibility that minimal privileges could mean only SELECT on certain tables, and only SELECT and UPDATE on other tables, etc. This is subject to change any time the application's functionality is enhanced. And there are weird cases, like the need to have SELECT privilege on a table you never query, because it's referenced by the foreign keys in a table you UPDATE. So tracking minimal privileges is a royal pain.

What are you trying to restrict by using SQL privileges? You're the one who wrote all the code, so managing SQL privileges at a fine granularity shouldn't be necessary. Frankly, if your users are able to upload and run SQL statements that you haven't vetted, you have bigger problems:

SELECT * FROM mytable, mytable, mytable, mytable, mytable ORDER BY 1;

The real tasks you want to govern aren't at the database level, they're at the application business level. For example, a CMS has operations like create a page, edit a page, administer comments, etc. These tasks are higher-level than SQL privileges. You could mimic them with SQL roles (which are groups of privileges), but SQL roles aren't widely supported.

I don't know anyone who maps their application users to distinct MySQL users. They're users you authenticate in your application, after the app has connected to the database (the users are just rows of data in the database).

So you're probably better off having your web app use a single MySQL user with full privileges.

Bill Karwin
great answer Bill, thanks. I might just see if anyone else wants to add anything before accepting it.
nickf
Interesting... but it seems insane that you should just give a user full privileges. Am I missing something here? Why not have a single "WebUser" who has read and write privileges for all DBs. Maybe not min. privlieges, but certainly not full. Why even invite the possibility for a user to do a "DROP MyDatabase;" command? Sure, your code SHOULDN'T allow raw sql to be executed... but mistakes are made, and this is just a lower level.
Atømix
@Atomiton: That would be fine, but it would mean that real administration tasks that require DDL commands must use different DB credentials or at least a different role. But people want to integrate the admin interface into the same web app. So should your app reconnect to the DB with different credentials on the fly? Or should you grant WebUser the union of privileges needed by any user of that app, even admins? I think most people choose the latter, for better or worse.
Bill Karwin
@Bill: I guess I'd just have a different connection string for my admin users. If they're logging in as an admin, connect with more rights. Maybe I'm just paranoid. I see what you mean by managing the permissions in the app, and you're right... it shouldn't let the user do harm. But I guess it's kind of like leaving your safe unlocked because you locked the door. Sometimes, you miss that window you left open. However, if the safe is locked, the important stuff is still safe. Similarly, locking the db down seems... well.. more safe. Pardon the pun. :)
Atømix
@Atomiton: How do you know the user is an admin in your app before they authenticate? And how do you authenticate before your app has connected to the database?
Bill Karwin
@Bill: You're right I don't. How I'd do it is have all users authenticate as a basic user. They can't start doing stuff until they log in. After login I will switch to using the appropriate connection string for subsequent requests. It means more work on the communications layer, but I typically would set up this layer once and use it for multiple projects. Of course, part of this is also dictated by our dba, who won't let me give full access to all users. ( She doesn't trust developers on her db server :-) )
Atømix
@Atomiton: This is the problem that SQL `ROLES` were designed to solve. These are groups of privileges that a user can adopt for the current session, provided your user has been granted that role by the DBA. See http://download-west.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_10004.htm Unfortunately, MySQL doesn't support SQL roles.
Bill Karwin
Cool! Thanks for the info!
Atømix
A: 

A web app usually uses just one user to access the DB, rather than a user per actual user account. Applying minimal privileges is good practice. The username and password is going to be coded into your script (does anyone obfuscate this?) so there's room for compromise if your scripts aren't managed properly.

In my experience, I very, very rarely have the app delete rows - much better to flag a row as deleted as you then have an audit of what is there rather than not knowing what was there! This approach also helps keep tables and indexes optimised.

Therefore, I would suggest allowing only INSERT, UPDATE and SELECT - it will quickly become apparent if parts of your app need to be relaxed a bit!

Allowing more privileges can only broaden the possibility for DoS attacks by issuing resource intensive commands, or allowing malicious data attacks.

Re: obfuscating db connect passwords: http://stackoverflow.com/questions/334776/whats-best-way-to-secure-a-database-connection-string
Bill Karwin
I did mean the single DB user for the entire application, not one DB user per actual user.
nickf