• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase
您的位置:首页 > 数据库 >Mysql > SQLServer 2008中的代码安全(一) 存储过程加密与安全上下文

SQLServer 2008中的代码安全(一) 存储过程加密与安全上下文

作者:匿名 字体:[增加 减小] 来源:互联网 时间:2018-12-05

匿名通过本文主要向大家介绍了存储过程,加密,安全等相关知识,希望本文的分享对您有所帮助

最近对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 OFF
GO
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

未加密的存储过程:

加密的存储过程:

此时,至少,存储过程的内容不会被轻易看到(虽然解密也是有可能的)。应用这个,我们可以对某些关键的存储过程进行加密。但此时,存储过程仍然能被。

除了加密sql文本的内容,我们还可以使用EXECUTE AS 子句设定存储过程的安全上下文,以满足不同的安全级别需求。

(关于EXECUTE AS 子句的详细用法,请参看MSDN:

此处,我们需要了解的是:

针对函数、过程、队列和触发器,对应的参数也不同。存储过程对应的参数包括(CALLER | SELF | OWNER | 'user_name')。

指定模块内的语句在模块调用方的上下文中执行。执行模块的用户不仅必须对模块本身拥有适当的权限,还要对模块引用的任何数据库对象拥有适当权限。 CALLER 是除队列外的所有模块的默认值,与 SQL Server 2005 行为相同。 CALLER 不能在 CREATE QUEUE 或 ALTER QUEUE 语句中指定。

EXECUTE AS SELF 与 EXECUTE AS 等价,其中指定用户是创建或更改模块的用户。创建或更改模块的用户的实际用户 ID 存储在 sys.sql_modules 或 sys.service_queues 目录视图的 execute_as_principal_id 列中。SELF 是队列的默认值。
OWNER 必须映射到单独帐户,不能是角色或组。
指定模块内的语句在 user_name 指定的用户的上下文中执行。将根据 user_name 来验证对模块内任意对象的权限。不能为具有服务器作用域的 DDL 触发器或登录触发器指定 user_name。请改用 login_name。user_name 必须存在于当前数据库中,并且必须是单独帐户。user_name 不能是组、角色、证书、密钥或内置帐户,如 NT AUTHORITY\LocalService、NT AUTHORITY\NetworkService 或 NT AUTHORITY\LocalSystem。执行上下文的用户 ID 存储在元数据中,可以在 sys.sql_modules 或 sys.assembly_modules 目录视图的 execute_as_principal_id 列查看。


。


我们看一个示例:
第一步、创建一个测试存储过程,用来delete表tb_Demo的所有数据
代码如下:
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

第二步:创建一个账号TonyZhang,并赋于该账号对该存储过程的exec权限
代码如下:
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

以该账号登录SQL Server,并执行:
代码如下:
EXECUTE dbo.CPP_DEL_ALL_Tb_Demo/**(4 row(s) affected)**/

注意:此时,虽然TonyZhang除了执行存储过程[CPP_DEL_ALL_Tb_Demo]之外没有任何其他权限,但仍然执行了存储过程,并删除了表记录。
如果我们修改存储过程为:
代码如下:
Alter PROCEDURE dbo.[CPP_DEL_ALL_Tb_Demo]
AS
-- Deletes all rows prior to the data feed
truncate table dbo.[tb_Demo]
GO

此时,再以TonyZhang登录,并执行存储过程,会提示:
这是因为所有者权链只限定SELECT、INSERT、UPDATE 和 DELETE。而不包括Truncate,换句话说,系统授于的Exec只既定于
有人可能会问:如果在存储过程内部调用动态语句,而不是明确的表名,我们如何限定权限呢?
第三步:我们建立一个存储过程,功能是传入一个参数表名,查询该表的记录数。
代码如下:
CREATE PROCEDURE dbo.[CPP_SEL_CountRowsFromAnyTable]
@SchemaAndTable nvarchar(255)
AS
EXEC ('SELECT COUNT(1) FROM ' + @SchemaAndTable)
GO

授于Tonyzhang 以执行该存储过程的权限:
代码如下:
GRANT EXEC ON dbo.[CPP_SEL_CountRowsFromAnyTable] to TonyZhang
go

此时,以Tonyzhang登录,执行存储过程,会提示:

注意,此时,。
第四步:修改存储过程的上下文
创建一个新账号jackwang,赋于表tb_Demo的select权限
代码如下:
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

注意:这样,我们再调用存储过程

小结:
本文通过简单的两个示例开始SQL server代码的安全之旅,
1、存储过程的加密,(注意:)
2、存储过程的安全上下文。可以通过上下文设置更加严格的数据访问级别。(主要是对)

后续部分将会涉及SQL server 2008新增的透明加密(TDE)功能。
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • mysql 精简过程(删除一些文件)
  • mysql存储过程 在动态SQL内获取返回值的方法详解
  • 深入mysql存储过程中表名使用参数传入的详解
  • 基于mysql多实例安装的深入解析
  • 深入mysql创建自定义函数与存储过程的详解
  • 基于Php mysql存储过程的详解
  • Mysql DNS反向解析导致连接超时过程分析(skip-name-resolve)
  • 一次非法关机导致mysql数据表损坏的实例解决
  • Mysql的游标的定义使用及关闭深入分析
  • mysql存储过程 游标 循环使用介绍

相关文章

  • 2017-05-11mysql 截取指定的两个字符串之间的内容
  • 2017-05-11MySQL死锁问题分析及解决方法实例详解
  • 2018-12-05mysql 忘记密码的解决方法(linux和windows小结)
  • 2018-12-05MSSQL 游标使用 心得
  • 2018-12-05MySQL 通过索引优化含ORDER BY的语句
  • 2018-12-05Mysql安全性测试
  • 2018-12-05MySQ中基本语法与语句的介绍
  • 2018-12-05mysql的安装信息如何在linux服务器下查看(图)
  • 2018-12-05Mysql数据控制语言
  • 2018-12-05mysql not in、left join、IS NULL、NOT EXISTS 效率问题记录

文章分类

  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase

最近更新的内容

    • 使用mysqli扩展技术实现多个数据表查询
    • mysql中用正则表达式进行搜索匹配教程(三)
    • Mysql函数 的相关讲解
    • sqlserver 中时间为空的处理小结
    • mysql仿asp的数据库操作类
    • mysql 10w级别的mysql数据插入
    • mysql常用的语句_MySQL
    • 你有没有遗忘mysql的历史记录
    • mssql2008 自定义表类型实现(批量插入或者修改)
    • 使用MySQL数据库(2)创建一个数据库

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有