If I have a user that only has limited permissions - just db_datareader and db_datawriter, which should only permit the user to query data and insert/edit/delete data, without allowing the user to add/modify/delete tables in the database.
There may be a need for the user to be able to execute stored procedures. If the user is given execute permissions (via the following sql: "GRANT EXECUTE TO UserName"), will the previous limitations (datareader and datawriter) still be enforced on what the user tries to execute through stored procedures? Or do Execute privileges really open up a pandora's box of other security holes (and if so, what)?
Granting execute permissions will allow that person to do anything which that stored procedure does in the context of that stored procedure (so if the sproc drops a table, the user will be able to execute the sproc to drop the table).
Edit, I just checked and I was wrong. Deny access does not revoke the ability to execute an action in a stored procedure.
Here is the article on MSDN which specifies that denying access does not affect a stored procedure.
http://msdn.microsoft.com/en-us/library/bb669058.aspx
UPDATE: What you might be able to do is execute a drop table command through sp_executeSQL in the stored procedure and deny the user the ability drop tables. That should prevent the stored procedure from being able to successfully execute the command (unless the user has the permissions to do so), since to use sp_executesql the user needs the permissions to perform the sql action and not just access to the stored procedure.
The concept you want is "ownership chaining"
Basically, permissions are not checked on objects in the same schema (say dbo) used by stored procedures. Except: deny is always checked.
So if stored proc dbo.uspDoStuff uses table dbo.Parent and dbo.Child, no permissions are needed on the tables and it just works. Unless you have run "
DENY SELECT ON dbo.Parent to MyUser
".Note: You'd normally do "CREATE ROLE MyRole", add the user to the role, and grant permissions on the role. db_datareader is just a special, reserved role for example.
Execute permissions do not open up any extra security holes. In my opinion a larger hole is the fact that users have direct read/write access to the tables.
Since SQL Server implements ownership chaining you can provide controllable, auditable access to data by revoking datareader/datawriter permissions and providing all data access through stored procedures where users only have execute permissions. This will ensure that someone cannot arbitrarily insert/update/delete from tables. It will also provide another layer in a defense in depth strategy as in the event that an application that uses the database is vulnerable to a SQL Injection attack the attacker cannot read from/write to any table they want to.
The only caveat with doing this is if you are using an ORM it may take some additional development effort to use sprocs rather than letting the ORM dynamically generate the SQL.
If the owner of the stored procedure has the rights to select, insert, update or delete against a table then select, insert, update and delete statements inside the stored procedure will execute as long as the caller has execute rights on the stored procedure, even if the caller does not have rights to directly perform select, insert, update or delete against the table.
However a stored procedure can not perform DDL unless the caller has rights to perform DDL even if the owner of the stored procedure has DDL rights. Note this also applies to truncate table.
Answer: In your case granting
db_datareader
anddb_datawriter
to a user already gives the user full DML on all tables. Granting execute on any stored procedure will not give any additional rights.Stored procedures can be used to increase data integrity by providing a gate through which all external programs must go. Do not grant insert, delete or update, but create SPs that do the work and enforce the appropriate rules about the data. (Above and beyond what can be done with constraints.) And as Joe Kuemerle points out, stored procedures can be used to increase security.
I have observed this behavior while developing an application on SQL Server 2000 and this even re-tested on SQL Server 2008 and found the same behavior. I have not been able to find documentation on this behavior.
Logged in as DBO and SA create a table:
Then create some stored procedures for basic DML:
As dbo, we can run the following SQL statements:
Or do the equivalent via the stored procedures
Now, create a DDL stored procedure and test:
And now create another user and grant execute rights to all the stored procedure. Do not grant any other rights. (Assumes public does not have extra rights and mixed mode authentication. Mixed mode authentication is not recommended, but makes testing how rights are handled easier.)
Login in as SoLogin. Try the DML:
Nothing but errors:
Try the basic DML stored procedures:
They work, because the owner of the SPs have the right rights, even though SoUser does not.
Try the truncate or drop stored procedure:
Errors again: