SQLServer 2008中的代碼平安(一) 存儲進程加密與平安高低文。本站提示廣大學習愛好者:(SQLServer 2008中的代碼平安(一) 存儲進程加密與平安高低文)文章只能為提供參考,不一定能成為您想要的結果。以下是SQLServer 2008中的代碼平安(一) 存儲進程加密與平安高低文正文
<一>存儲進程加密
其實,用了這十多年的SQL server,我曾經成了存儲進程的忠誠擁趸。在直接應用SQL語句照樣存儲進程來處置營業邏輯時,我根本會絕不遲疑地選擇後者。
來由以下:
1、應用存儲進程,至多在防不法注入(inject)方面供給更好的掩護。至多,存儲進程在履行前,起首會履行預編譯,(假如因為不法參數的緣由)編譯失足則不會履行,這在某種水平上供給一層自然的樊籬。
我至今還記得年夜約8、九年前采取的一個權限掌握體系就是經由過程拼集一個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
未加密的存儲進程:
加密的存儲進程:
此時,至多,存儲進程的內容不會被隨意馬虎看到(固然解密也是有能夠的)。運用這個,我們可以對某些症結的存儲進程停止加密。但此時,存儲進程依然能被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')。
■CALLER 指定模塊內的語句在模塊挪用方的高低文中履行。履行模塊的用戶不只必需對模塊自己具有恰當的權限,還要對模塊援用的任何數據庫對象具有恰當權限。 CALLER 是除隊列外的一切模塊的默許值,與 SQL Server 2005 行動雷同。 CALLER 不克不及在 CREATE QUEUE 或 ALTER QUEUE 語句中指定。
■SELF EXECUTE AS SELF 與 EXECUTE AS user_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 AUTHORITY\LocalService、NT AUTHORITY\NetworkService 或 NT AUTHORITY\LocalSystem。履行高低文的用戶 ID 存儲在元數據中,可以在 sys.sql_modules 或 sys.assembly_modules 目次視圖的 execute_as_principal_id 列檢查。
2、一切權鏈具有以上限制:
僅實用於 DML 語句:SELECT、INSERT、UPDATE 和 DELETE。
挪用和被挪用對象的一切者必需雷同。
不實用於模塊內的靜態查詢。
我們看一個示例:
第一步、創立一個測試存儲進程,用來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只既定於SELECT、INSERT、UPDATE 和 DELETE
有人能夠會問:假如在存儲進程外部挪用靜態語句,而不是明白的表名,我們若何限制權限呢?
第三步:我們樹立一個存儲進程,功效是傳入一個參數表名,查詢該表的記載數。
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登錄,履行存儲進程,會提醒:
留意,此時,tonyzhang固然有履行存儲進程的權限,然則沒有參數表的select權限,所以履行掉敗。
第四步:修正存儲進程的高低文
創立一個新賬號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
留意:如許,我們再挪用存儲進程[CPP_SEL_CountRowsFromAnyTable]時,會主動以JackWang的身份運轉該存儲進程。
此時,我們仍以Tonyzhang登錄,再履行:
小結:
本文經由過程簡略的兩個示例開端SQL server代碼的平安之旅,
1、存儲進程的加密,(留意:加密存儲進程前應當備份原始存儲進程,且加密應當在安排到臨盆情況前完成。)
2、存儲進程的平安高低文。可以經由過程高低文設置加倍嚴厲的數據拜訪級別。(重要是對SELECT、INSERT、UPDATE 和 DELETE語句的拜訪限制)
後續部門將會觸及SQL server 2008新增的通明加密(TDE)功效。