浅析SQL Server 2008中的代码安全之一:存储过程加密与安全上下文.docx_第1页
浅析SQL Server 2008中的代码安全之一:存储过程加密与安全上下文.docx_第2页
浅析SQL Server 2008中的代码安全之一:存储过程加密与安全上下文.docx_第3页
浅析SQL Server 2008中的代码安全之一:存储过程加密与安全上下文.docx_第4页
浅析SQL Server 2008中的代码安全之一:存储过程加密与安全上下文.docx_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

最近对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,将您的业务逻辑乱改一通,而恰巧您五分钟前又没做备份,那会怎么样?)(注意:加密存储过程前应该备份原始存储过程,且加密应该在部署到生产环境前完成。)存储过程的加密非常简单,我们看一个例子:插入测试表1. usetestDb2 2. go 3. /*测试表*/ 4. SETANSI_PADDINGON5. GO 6. CREATETABLEdbo.tb_demo( 7. idintNOTNULL, 8. submitdatedatetimeNULL, 9. commmentnvarchar(200)NULL, 10. ) 11. GO 12. SETANSI_PADDINGOFFGO 13. Insertintotb_demo 14. select1024,getdate(),REPLICATE(A,100); 15. WAITFORDELAY00:00:04; 16. Insertintotb_demo 17. select1024,getdate(),REPLICATE(B,50); 18. go插入存储过程1. /*创建未加密的存储过程*/ 2. CreateProcedureCPP_test_Original 3. AS4. select*fromtb_demo 5. go 6. /*创建加密的存储过程*/ 7. CreateProcedureCPP_test_Encryption 8. withencryption 9. AS10. -可以换成任意的逻辑 11. executeCPP_test_Original 12. go未加密的存储过程:加密的存储过程:此时,至少,存储过程的内容不会被轻易看到(虽然解密也是有可能的)。应用这个,我们可以对某些关键的存储过程进行加密。但此时,存储过程仍然能被execute、alter和drop。安全上下文除了加密sql文本的内容,我们还可以使用EXECUTE AS子句设定存储过程的安全上下文,以满足不同的安全级别需求。如果你对这些不感兴趣,请直接路过带下划线的段落。(关于EXECUTE AS子句的详细用法,请参看MSDN:/zh-cn/library/ms188354.aspx)此处,我们需要了解的是:1、在 SQL Server 中,可以定义以下用户定义模块的执行上下文:函数(内联表值函数除外)、过程、队列和触发器。通过指定执行模块的上下文,可以控制数据库引擎使用哪一个用户帐户来验证对模块引用的对象的权限。这有助于人们更灵活、有力地管理用户定义的模块及其所引用对象所形成的对象链中的权限。必须而且只需授予用户对模块自身的权限,而无需授予用户对被引用对象的显式权限。只有运行模块的用户必须对模块访问的对象拥有权限。针对函数、过程、队列和触发器,对应的参数也不同。存储过程对应的参数包括(CALLER | SELF | OWNER | user_name)。CALLER 指定模块内的语句在模块调用方的上下文中执行。执行模块的用户不仅必须对模块本身拥有适当的权限,还要对模块引用的任何数据库对象拥有适当权限。 CALLER 是除队列外的所有模块的默认值,与 SQL Server 2005 行为相同。 CALLER 不能在 CREATE QUEUE 或 ALTER QUEUE 语句中指定。SELF EXECUTE AS SELF 与 EXECUTE ASuser_name等价,其中指定用户是创建或更改模块的用户。创建或更改模块的用户的实际用户 ID 存储在sys.sql_modules或sys.service_queues目录视图的execute_as_principal_id列中。SELF 是队列的默认值。OWNER 指定模块内的语句在模块的当前所有者上下文中执行。如果模块没有指定的所有者,则使用模块架构的所有者。不能为 DDL 或登录触发器指定 OWNER。注意:OWNER 必须映射到单独帐户,不能是角色或组。user_name 指定模块内的语句在 user_name 指定的用户的上下文中执行。将根据 user_name 来验证对模块内任意对象的权限。不能为具有服务器作用域的 DDL 触发器或登录触发器指定 user_name。请改用 login_name。user_name 必须存在于当前数据库中,并且必须是单独帐户。user_name 不能是组、角色、证书、密钥或内置帐户,如 NT AUTHORITYLocalService、NT AUTHORITYNetworkService 或 NT AUTHORITYLocalSystem。执行上下文的用户 ID 存储在元数据中,可以在 sys.sql_modules 或 sys.assembly_modules 目录视图的 execute_as_principal_id 列查看。2、所有权链具有以下限制:仅适用于 DML 语句:SELECT、INSERT、UPDATE 和 DELETE。调用和被调用对象的所有者必须相同。不适用于模块内的动态查询。我们看一个示例:第一步、创建一个测试存储过程,用来delete表tb_Demo的所有数据1. USEtestDb2 2. GO 3. CREATEPROCEDUREdbo.CPP_DEL_ALL_Tb_Demo 4. AS5. -Deletesallrowspriortothedatafeed 6. DELETEdbo.tb_Demo 7. GO第二步:创建一个账号TonyZhang,并赋于该账号对该存储过程的exec权限1. USEmaster 2. GO 3. CREATELOGINTonyZhangWITHPASSWORD=123b3b44. USEtestDb2 5. GO 6. CREATEUSERTonyZhang 7. GO 8. GRANTEXECONdbo.CPP_DEL_ALL_Tb_DemotoTonyZhang以该账号登录SQL Server,并执行:1. EXECUTEdbo.CPP_DEL_ALL_Tb_Demo 2. /* 3. (4row(s)affected) 4. */注意:此时,虽然TonyZhang除了执行存储过程CPP_DEL_ALL_Tb_Demo之外没有任何其他权限,但仍然执行了存储过程,并删除了表记录。如果我们修改存储过程为:1. AlterPROCEDUREdbo.CPP_DEL_ALL_Tb_Demo 2. AS3. -Deletesallrowspriortothedatafeed 4. truncatetabledbo.tb_Demo 5. GO此时,再以TonyZhang登录,并执行存储过程,会提示:这是因为所有者权链只限定在SELECT、INSERT、UPDATE 和 DELETE。而不包括Truncate,换句话说,系统授于的Exec只既定于SELECT、INSERT、UPDATE 和 DELETE有人可能会问:如果在存储过程内部调用动态语句,而不是明确的表名,我们如何限定权限呢?第三步:我们建立一个存储过程,功能是传入一个参数表名,查询该表的记录数。1. CREATEPROCEDUREdbo.CPP_SEL_CountRowsFromAnyTable 2. SchemaAndTablenvarchar(255) 3. AS4. EXEC(SELECTCOUNT(1)FROM+SchemaAndTable) 5. GO授于Tonyzhang 以执行该存储过程的权限:1. GRANTEXECONdbo.CPP_SEL_CountRowsFromAnyTabletoTonyZhang 2. go此时,以Tonyzhang登录,执行存储过程,会提示:注意,此时,tonyzhang虽然有执行存储过程的权限,但是没有参数表的select权限,所以执行失败。第四步:修改存储过程的上下文创建一个新账号jackwang,赋于表tb_Demo的select权限1. USEmaster 2. GO 3. CREATELOGINJackWangWITHPASSWORD=123b3b44. USETestdb2 5. GO 6. CREATEUSERJackWang 7. GRANTSELECTONOBJECT:dbo.tb_DemoTOJackWang 8. GO 9. /* 10. 注意:此时,JackWang可以执行dbo.tb_Demo的Select 11. */修改存储的执行者1. USETestdb2 2. GO 3. alterPROCEDUREdbo.CPP_SEL_CountRowsFromAnyTable 4. SchemaAndTablenvarchar(255) 5. WITHEXECUTEASJackWang6. AS7. EXEC(SELECTCOUNT(1)FROM+SchemaAndTable) 8. GO注意:这样,我们再调用存储过程CPP_SEL_CountRowsFromAnyTable时,会自动以JackWang的身份运行该存储过程。此时,我们仍以Tonyzhang登录,再执行:小结:本文通过简单的两个示例开始SQL s

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论