首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 2008 程式碼安全實戰(一):預存程序加密與 EXECUTE AS 基礎

     編輯:關於SqlServer

前言:為何堅持使用預存程序?

十多年 SQL Server 實戰經驗讓我成為預存程序的忠實擁護者。在「直寫 SQL」與「預存程序」的選擇上,我毫不猶豫選後者,核心理由有三:

  1. 天然防 SQL 注入:預存程序預先編譯,參數型別檢查在編譯期完成,非法參數導致編譯失效,形成第一道防線。
  2. 細粒度存取控制:應用僅獲預存程序 EXECUTE 權限,無法直接 SELECT * 基表,實現行級、列級管控。
  3. 原始碼加密保護:WITH ENCRYPTION 讓邏輯在目錄檢視中不可讀,防止托管環境或注入攻擊洩露核心業務邏輯。

⚠️ 重要提醒:加密前務必備份原始碼,且應在部署生產環境前完成加密。

一、預存程序加密實作

建立測試表與資料

USE testDb2; GO
CREATE TABLE dbo.tb_demo (
    id INT NOT NULL,
    submitdate DATETIME NULL,
    commment NVARCHAR(200) NULL
);
INSERT tb_demo SELECT 1024, GETDATE(), REPLICATE('A',100);
WAITFOR DELAY '00:00:04';
INSERT tb_demo SELECT 1024, GETDATE(), REPLICATE('B',50);

建立未加密與加密版本對比

-- 未加密
CREATE PROCEDURE CPP_test_Original
AS SELECT * FROM tb_demo; GO

-- 加密
CREATE PROCEDURE CPP_test_Encryption
WITH ENCRYPTION
AS EXEC CPP_test_Original; GO

驗證效果

未加密:sp_helptext 或 SSMS 可直接檢視定義。

未加密程序碼可見

加密後:定義顯示為 Encrypted,無法還原(雖然第三方工具可破解,但大幅提高門檻)。

加密後程序碼不可見

注意:加密不防止 EXECUTE、ALTER、DROP 操作,僅隱藏定義文本。

二、安全執行上下文:EXECUTE AS 詳解

除了加密文本,EXECUTE AS 子句可設定模組執行身分,滿足多層次安全需求。(詳細語法請參考 MSDN)

適用模組與核心優勢

  • 適用:函數(內聯表值函數除外)、預存程序、佇列、觸發器。
  • 優勢:只需授予使用者模組本身的權限,無需授予被引用物件的顯式權限,打破權限鏈依賴。

預存程序的四種 EXECUTE AS 選項

選項行為描述備註
CALLER以呼叫者身分執行(預設)。呼叫者需同時擁有模組與被引用物件權限。SQL Server 2005 行為相容
SELF等同 EXECUTE AS '建立者'。建立者 SID 存於 sys.sql_modules.execute_as_principal_id。佇列預設值
OWNER以模組目前擁有者身分執行。無指定擁有者則用結構描述擁有者。擁有者必須為單一帳號,不可為角色/群組;DDL/登入觸發器不可用
'user_name'指定資料庫使用者身分執行。需存在於目前資料庫,且為單一帳號。最靈活,常用於建立專用代理帳號

所有權鏈的三大限制(必背)

  1. 僅適用於 DML:SELECT、INSERT、UPDATE、DELETE。
  2. 呼叫端與被呼叫端擁有者必須相同。
  3. 不適用於模組內的動態查詢(EXEC('...')、sp_executesql)。

小結與延伸閱讀

  • 加密保護「靜態程式碼」,EXECUTE AS 控制「執行時權限」,兩者互補。
  • 下一篇將實戰示範:TRUNCATE 導致所有權鏈斷裂、動態 SQL 權限失效,以及如何用代理帳號破解。

版權聲明:本文版權由邀月與博客園共同所有,轉載請註明出處。助人等於自助!

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved