最近对SQL Server 2008的安全入门略作小结,以作备忘。本文主要是针对存储过程加密与安全来作分析。
网站建设哪家好,找创新互联!专注于网页设计、网站建设、微信开发、微信小程序定制开发、集团企业网站建设等服务项目。为回馈新老客户创新互联还提供了云龙免费建站欢迎大家使用!
<一>存储过程加密
其实,用了这十多年的SQL server,我已经成了存储过程的忠实拥趸。在直接使用SQL语句还是存储过程来处理业务逻辑时,我基本会毫不犹豫地选择后者。
理由如下:
1、使用存储过程,至少在防非法注入(inject)方面提供更好的保护。因为,存储过程在执行前,首先会执行预编译,(如果由于非法参数的原因)编译出错则不会执行,这要某种程度上提供一层天然的屏障。
我至今还记得大约八、九年前采用的一个权限控制系统就是通过拼凑一个SQL语句,最终得到了一个形如“ where 1=1 and dataID in (1,2) and ModelID in (2,455) And ShopID in (111) and departID in ( 1,3) and ([Name] like %myword%) ”的where条件子句来获取符合条件的结果集。
注意:这个参数是通过地址栏web应用的地址栏或Winform的UI界面来输入的,所以对恶意注入需要花费一定的成本来维护。因为一些常用的关键字(或敏感词)很难区分是恶意或非恶意。
2、使用存储过程而不是直接访问基表,可以提供更好的安全性。你可以在行级或列级控制数据如何被修改。相对于表的访问,你可以确认有执行权限许可的用户执行相应的存储过程。这也是访问数据服务器的惟一调用途径。因此,任何偷窥者将无法看到你的SELECT语句。换句话说,每个应用只能拥有相应的存储过程来访问基表,而不是“SLEECT *”。
3、存储过程可以加密。(这点非常实用,设想一下,您的数据库服务器是托管的或租用的,你是否能心安理得的每天睡个安稳觉。如果竞争对手“一不小心”登上你的SQL Server,或通过注入得到了你的存储过程,然后相应的注入恶意的SQL,将您的业务逻辑乱改一通,而恰巧您五分钟前又没做备份,那会怎么样?)
(注意:加密存储过程前应该备份原始存储过程,且加密应该在部署到生产环境前完成。)
存储过程的加密非常简单,我们看一个例子:
插入测试表
- use testDb2
- go
- /**********测试表*****************/
- SET ANSI_PADDING ON
- GO
- CREATE TABLE [dbo].[tb_demo](
- [id] [int] NOT NULL,
- [submitdate] [datetime] NULL,
- [commment] [nvarchar](200) NULL,
- )
- GO
- SET ANSI_PADDING OFFGO
- Insert into [tb_demo]
- select 1024, getdate(),REPLICATE('A',100);
- WAITFOR DELAY '00:00:04';
- Insert into [tb_demo]
- select 1024, getdate(),REPLICATE('B',50);
- go
插入存储过程
- /***************创建未加密的存储过程*******************/
- Create Procedure CPP_test_Original
- AS
- select * from [tb_demo]
- go
- /***************创建加密的存储过程*******************/
- Create Procedure CPP_test_Encryption
- with encryption
- AS
- ----可以换成任意的逻辑
- execute CPP_test_Original
- go
未加密的存储过程:
加密的存储过程:
此时,至少,存储过程的内容不会被轻易看到(虽然解密也是有可能的)。应用这个,我们可以对某些关键的存储过程进行加密。但此时,存储过程仍然能被execute、alter和drop。
<二>安全上下文
除了加密sql文本的内容,我们还可以使用EXECUTE AS 子句设定存储过程的安全上下文,以满足不同的安全级别需求。
如果你对这些不感兴趣,请直接路过带下划线的段落。
(关于EXECUTE AS 子句的详细用法,请参看MSDN:http://msdn.microsoft.com/zh-cn/library/ms188354.aspx)
此处,我们需要了解的是:
1、在 SQL Server 中,可以定义以下用户定义模块的执行上下文:函数(内联表值函数除外)、过程、队列和触发器。
通过指定执行模块的上下文,可以控制数据库引擎使用哪一个用户帐户来验证对模块引用的对象的权限。这有助于人们更灵活、有力地管理用户定义的模块及其所引用对象所形成的对象链中的权限。必须而且只需授予用户对模块自身的权限,而无需授予用户对被引用对象的显式权限。只有运行模块的用户必须对模块访问的对象拥有权限。
针对函数、过程、队列和触发器,对应的参数也不同。存储过程对应的参数包括(CALLER | SELF | OWNER | 'user_name')。
- USE testDb2
- GO
- CREATE PROCEDURE dbo.[CPP_DEL_ALL_Tb_Demo]
- AS
- -- Deletes all rows prior to the data feed
- DELETE dbo.[tb_Demo]
- GO
- USE master
- GO
- CREATE LOGIN TonyZhang WITH PASSWORD = '123b3b4'
- USE testDb2
- GO
- CREATE USER TonyZhang
- GO
- GRANT EXEC ON dbo.[CPP_DEL_ALL_Tb_Demo] to TonyZhang
- EXECUTE dbo.CPP_DEL_ALL_Tb_Demo
- /**
- (4 row(s) affected)
- **/
- Alter PROCEDURE dbo.[CPP_DEL_ALL_Tb_Demo]
- AS
- -- Deletes all rows prior to the data feed
- truncate table dbo.[tb_Demo]
- GO
- CREATE PROCEDURE dbo.[CPP_SEL_CountRowsFromAnyTable]
- @SchemaAndTable nvarchar(255)
- AS
- EXEC ('SELECT COUNT(1) FROM ' + @SchemaAndTable)
- GO
- GRANT EXEC ON dbo.[CPP_SEL_CountRowsFromAnyTable] to TonyZhang
- go
- USE master
- GO
- CREATE LOGIN JackWang WITH PASSWORD = '123b3b4'
- USE Testdb2
- GO
- CREATE USER JackWang
- GRANT SELECT ON OBJECT::dbo.[tb_Demo] TO JackWang
- GO
- /*******
- 注意:此时,JackWang 可以执行dbo.[tb_Demo的Select
- *******/
- USE Testdb2
- GO
- alter PROCEDURE dbo.[CPP_SEL_CountRowsFromAnyTable]
- @SchemaAndTable nvarchar(255)
- WITH EXECUTE AS 'JackWang'
- AS
- EXEC ('SELECT COUNT(1) FROM ' + @SchemaAndTable)
- GO
原文链接:http://www.cnblogs.com/downmoon/archive/2011/02/28/1966662.html
【编辑推荐】
网站名称:浅析SQLServer2008中的代码安全之一:存储过程加密与安全上下文
路径分享:http://www.36103.cn/qtweb/news38/17288.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联