SQL Mail 與 SQL Server Agent 在相同安全性內容下執行,預設使用本地系統帳號。若使用者擁有執行擴展預存程序 xp_sendmail 的權限,便可透過其附件參數存取伺服器檔案系統,構成嚴重安全漏洞。
核心做法是建立一個自訂預存程序(如 sp_sendmail)封裝 xp_sendmail,僅開放必要參數,並移除 xp_sendmail 的 PUBLIC 執行權限。所有寄信需求均透過此包裝程序處理,達到權限最小化原則。
USE master;
GO
IF EXISTS (SELECT name FROM sysobjects WHERE name = N'sp_sendmail' AND type = 'P')
DROP PROCEDURE sp_sendmail;
GO
CREATE PROCEDURE sp_sendmail
@in_recipients VARCHAR(8000) = '',
@in_message VARCHAR(8000) = 'test',
@in_query VARCHAR(8000) = '',
@in_copy_recipients VARCHAR(8000) = NULL,
@in_blind_copy_recipients VARCHAR(8000) = NULL,
@in_subject VARCHAR(80) = 'test',
@in_type VARCHAR(80) = NULL,
@in_attach_results VARCHAR(80) = NULL,
@in_no_output VARCHAR(8) = NULL,
@in_no_header VARCHAR(8) = NULL,
@in_width INT = 10,
@in_separator VARCHAR(8) = NULL,
@in_echo_error VARCHAR(8000) = NULL,
@in_set_user VARCHAR(256) = NULL,
@in_dbuse VARCHAR(256) = NULL
AS
BEGIN
DECLARE @attachments VARCHAR(8000);
-- 強制加入 DBA 副本,確保審計追蹤
SET @in_recipients = ';' + @in_recipients;
EXEC master..xp_sendmail
@recipients = @in_recipients,
@message = @in_message,
@query = @in_query,
@attachments = ' ', -- 禁止自訂附件,防止檔案系統存取
@copy_recipients = @in_copy_recipients,
@blind_copy_recipients = @in_blind_copy_recipients,
@subject = @in_subject,
@type = @in_type;
-- 其他參數依需求決定是否透傳
END;
GO
sp_sendmail 權限:GRANT EXECUTE ON sp_sendmail TO [AppRole]xp_sendmail 的執行權限:REVOKE EXECUTE ON xp_sendmail TO PUBLIC透過封裝 xp_sendmail 並移除其公開權限,能有效封堵檔案系統存取風險,同時保留應用程式寄信功能,符合最小權限原則,是 SQL Server 安全加固的重要一環。