当前位置: 代码迷 >> 综合 >> SqlServer2008实例52存储过程安全
  详细解决方案

SqlServer2008实例52存储过程安全

热度:14   发布时间:2024-02-11 06:58:41.0

1.加密存储过程

    存储过程的T-SQL定义能在数据库中实现内容加密,这样就不能读取过程的定义。在后端使用SQL Server的软件开发商通常加密存储过程来防止客户端或竞争对手的篡改或逆向工程。如果你使用了加密,请确保保存了原始的T-SQL定义,因为以后不能再轻易地解密它(合法并且可靠的)。而且应该只在正式把它部署到生产环境之前才进行加密。
要加密存储过程,可以在新存储过程的名字后面指定WITH ENCRYPTION:

USE AdventureWorks
GOCREATE PROC dbo.usp_SEL_EmployeePayHistory
WITH ENCRYPTION
ASSELECT EmployeeID,RateChangeDate,Rate,Payfrequency,ModifiedDate
FROM HumanResources.EmployeePayHistoryGO

一旦创建了WITH ENCRYPTION,就不能再看到过程的文本定义:

--查看过程的文本
EXEC sp_helptext usp_SEL_EmployeePayHistory

    加密能使用CREATE PROCEBURE或ALTER PROCEDURE来定义,但是要确保保存了你的源代码,因为既有的已加密文本不能被轻易解密。

2.使用EXECUTE AS 来指定过程的安全上下文

  WITH EXECUTE AS关键字允许你指定存储过程执行所在的安全上下文,覆盖存储过程调用者的默认安全。在这里,安全上下文是指用户执行存储过程的权限。
可以在以下几个权限下执行存储过程:

  •     调用者的安全上下文:
  •     过程的编写者或最终修改者:
  •     指定的登录名(如果你有那个登录名的IMPERSONATE(模拟)权限):
  •     存储过程的拥有者。

    首先,先简单介绍一下调用者权限和所有权链。当创建一个对象(例如存储过程或视图)并将其用来对另外一个数据库对象进行INSERT、UPDATE、DELETE或SELECT的对象的时候,就出现了所有权链。如果存储过程对象的架构和它引用对象的架构一样,SQL Server只会检测存储过程调用者是否有对存储过程的.EXECUTE权限。再次说,所有权链仅仅应用于INSERT、UPDATE、DELETE或SELECT命令。可以授予用户执行存储过程的权限,而不用给他们对基础表的访问权限——这就是为什么存储过程对数据库的安全非常好。
然而,当发现执行的命令不是INSERT、UPDATE、DELETE或SELECT时,问题就来了。在这些情况下,即使调用者对存储过程有EXECUTE权限,例如使用TRUNCATE TABLE命令来截断表,仍然先需要有使用TRUNCATE TABLE命令的权限。例如,创建下面的存储过程来删除表中的所有数据:

USE AdventureWorks
GOCREATE PROC dbo.usp_DEL_AllEmployeeSalary
AS
--在数据进来之前删除所有行
DELETE dbo.EmployeeSalary
GO

创建并填充dbo.EmployeeSalary表来设置这个环境:

USE AdventureWorks
GOCREATE TABLE dbo.EmployeeSalary
(EmployeeID int NOT NULL PRIMARY KEY CLUSTERED,
SalaryAMT money NOT NULL)
GOINSERT dbo.EmployeeSalary(EmployeeID,SalaryAMT)
VALUES (1,45000.00),(343,100000.00),(93,3234933.00)

然后,将对新存储过程的EXECUTE权限授予你的雇员BrainG:

USE master
GOCREATE LOGIN BrianG WITH PASSWORD='123'USE AdventureWorks
GOCREATE USER BrianG
GO
GRANT EXEC ON usp_DEL_AllEmployeeSalary to BrianG
GO

现在,如果BrainG尝试执行这个过程,就建立了他的所有权链:

EXECUTE dbo.usp_DEL_AllEmployeeSalary

虽然BrainG除了有执行这个新存储过程的权限之外在数据库中没有其他权限,但是他仍然成功了。 

  相关解决方案