Providing direct access on tables for application user accounts is always a security concern. But, there are some scenarios which forces us to do the same. I previously discussed it in detail over here. SQL Server 2008/2005 provides a few options to avoid providing direct rights, even when the stored procedure involves dynamic sql, DDL, cross database reference etc. This post will explore one such option.
Execute AS option:
While creating stored procedures, we can specify EXECUTE AS clause to run the stored procedure under a different account. For example consider the following
CREATE PROCEDURE dbo.Rights_check
AS
BEGIN
DECLARE @txt NVARCHAR(100)
SET @txt = 'Select * from databaselog'
EXEC Sp_executesql @txt
END
GO
Let us grant rights to account test1, which doesn't have direct access to 'databaselog' table.
GRANT EXEC ON dbo.rights_check TO test1
GO
Executing the 'dbo.rights_check' procedure from 'test1' account fails as test1 doesn't have direct access on 'databaselog' table.Using 'Execute As' clause can allow test1 to execute 'dbo.rights_check' procedure successfully without directly providing rights on the 'databaselog' table.
ALTER PROCEDURE dbo.Rights_check
WITH EXECUTE AS owner
AS
BEGIN
DECLARE @txt NVARCHAR(100)
SET @txt = 'Select * from databaselog'
EXEC Sp_executesql @txt
END
I have just added the EXECUTE as OWNER clause on top which ensures that the stored procedure is executed in the context of owner of the stored procedure. Execution of the stored procedure using test1 is successful as expected.
The reason is, adding EXECUTE as OWNER allows any account which has execution rights on the stored procedure to execute under the security context of the owner of the stored procedure. This ensures that the executing account is allowed to obtain the special permissions only within the stored procedure and not outside the scope of it.
EXECUTE AS clause provides additional options like EXECUTE as 'user_name'. EXECUTE as 'user_name' allows one to execute under the context of particular user account instead of owner of the object.More details on the same can be read here.
EXECUTE AS clause effectively solves the security problems that arise when DDL statements, dynamic sql, cross database references are used.Digital Signatures, introduced in SQL Server 2005 also helps in addressing similar security problems which we will cover in the next post.
Sunday, September 12, 2010
Avoiding Explicit Permission - Execute as clause
Tuesday, August 17, 2010
Stored Procedures , Explicit Permissions and Security concerns
Its always a good practice to have your code wrapped in stored procedures.
One of the reasons is Security. To explain a bit more, when one grants execution rights on a stored procedure to a user, the user gets the rights to perform all the operations ( Select/Insert/update/delete ) within the stored procedure.However, the same user cannot perform the operations outside the context of stored procedure.
Ex:
GRANT EXEC ON dbo.usp_stored_proc TO user1
Assume that the stored proc dbo.usp_stored_proc performs Select and update on table1, then user1 can perform these operations only while executing dbo.usp_stored_proc and not directly. In other words, user1 cannot bypass the stored procedure and directly perform a select/update on table1.
But there are a few operations, where one needs to explictly grant permission to a object inside a stored procedure.In other words, its not enough if we just grant EXEC rights on the stored procedure. Let me list down such scenarios.
1) Using Dynamic sql queries using sp_executesql / EXEC :
If your stored procedure is using Dynamic SQL using sp_executesql then the
objects accessed in the dynamic sql require explicit permissions.
For Example
CREATE PROCEDURE dbo.Usp_stored_proc
AS
BEGIN
DECLARE @dsql NVARCHAR(100)
SET @dsql = ' Select * from table1 '
EXEC Sp_executesql @dsql
END
GO
For the above stored procedure, its not enough if we grant execution rights to
dbo.usp_stored_proc. In addition,one needs to grant select rights on 'table1' for the user executing stored procedure. Explicit grant is required because dynamic sql are always treated as separate batch outside the scope of the stored procedure.
2) Cross database reference
If you are accessing a table on another database, then one needs to explicitly grant rights.
CREATE PROCEDURE dbo.Usp_stored_proc
AS
BEGIN
SELECT empid,
salary,
increment,
name
FROM hr_database.dbo.salary
WHERE username = 'clerk';
.......
...........
Some code
..........
...........
END
GO
In the above stored procedure, the salary from database 'HR_database' is accessed. The user who calls the stored procedure should have rights on the HR_database.dbo.salary for the stored procedure to execute successfully.
Please note that the above scenario is true, when cross database ownership chaining is not enabled.If cross database ownership chaining is enabled, and if both the objects(dbo.usp_stored_proc and HR_database.dbo.salary;) belong to the same owner, then explicit permissions need not be granted.
3) While using linked servers
CREATE PROCEDURE dbo.Usp_stored_proc
AS
BEGIN
SELECT *
FROM linkedserver.DATABASE.dbo.table2;
END
GO
On the above stored procedure, linked server is used to refer to a table in a remote server.In such a case, the login that maps the user ( executing the stored procedure ) to the remote server should have select rights on table2. For understanding login mappings on linked server refer here.
4) Using DDL statements
CREATE PROCEDURE dbo.Usp_stored_proc
AS
BEGIN
TRUNCATE TABLE dbo.t1;
END
GO
If the stored procedure contains DDL statement like truncate,alter table, Create index then appropriate rights should be granted to caller of the stored procedure.Meagre execution rights on the stored procedure wouldnt suffice.
On all the four scenarios listed above, ideally one would want the caller of the stored procedure to use these extra permissions only while executing the stored procedure. At the rest of the time, we wouldnt want the caller to gain direct access on the table.But by granting the rights explicitly, the caller of the stored procedure gets additional rights to perform the above mentioned operations without executing the stored procedure. ie, anyone can use the calling account and connect to the database and perform a Select on a entire salary table on HR_database or truncate a table t1, without executing stored procedure. Obviously, this can be a serious security concern.
To prevent the same, there are a few excellent options in SQL Server 2005, SQL Server 2008 which will be discussed in the next post.