Sql-Server
我想知道 SQL Server 2012 是否保護 msdb.dbo.sp_send_dbmail 參數?
我使用這個系統儲存過程
dbo.sp_send_dbmail
從我的數據庫發送電子郵件,我想知道這個過程是否可以防止 SQL 注入?如果你有一些參考,這對我來說是有用的。
提前致謝。
遺憾的是,您可以毫無問題地進行 SQL 注入。這是我剛剛使用提升的帳戶執行的一個簡單測試,結果包括:
USE [master] GO DECLARE @msgbody NVARCHAR(4000) SET @msgbody = N'Test to see if this SP can suffer from SQL Injection' + CHAR(13) + CHAR(10) + CHAR(13) + CHAR(10) EXEC msdb.dbo.sp_send_dbmail @profile_name='MyDBMailProfile' , @recipients = 'john.eisbrener@Contoso.com' , @reply_to = 'john.eisbrener@Contoso.com' , @subject = 'SQL Injection Test' , @query = 'CREATE TABLE MyDB.dbo.johnSITest ( ID INT IDENTITY(1,1) , VAL VARCHAR(50) ) INSERT INTO MyDB.dbo.johnSITest (VAL) VALUES (''yes''), (''you''), (''can'')' , @body = @msgbody GO Mail (Id: 36756) queued. SELECT * FROM MyDB.dbo.johnSITest GO ID VAL ----------- -------------------------------------------------- 1 yes 2 you 3 can (3 row(s) affected) DROP TABLE MyDB.dbo.johnSITest GO
現在,如果執行它的帳戶沒有提升的權限,這應該會限制 SP 的曝光。帳戶執行此 SP 所需的最低權限如下:
權限
sp_send_dbmail的執行權限預設授予msdb數據庫中****DatabaseMailUser數據庫角色的所有成員。但是,當發送消息的使用者無權使用請求的配置文件時,sp_send_dbmail將返回錯誤並且不發送消息。
最小權限原則應始終規定您的安全方法,但同樣,它可以像任何攝取動態 SQL 的東西一樣被 SQL 注入。
**編輯:**為了回答您在評論中提出的後續問題,您可以通過將呼叫包裝在另一個靜態定義或更嚴格控制參數的
sp_send_dbmail
儲存過程中來進一步鎖定它。@query
然後,這個新的 SP 可以利用模擬(ref1,ref2),然後您只需向EXECUTE
您想要公開此功能的顯式使用者授予權限。這應該可以很好地鎖定事情,並且取決於您如何限制@query
傳遞給的參數的使用sp_send_dbmail
,您可能能夠完全消除普通帳戶發生 SQL 注入的可能性。同樣,任何可以直接呼叫的提升帳戶sp_send_dbmail
仍然有能力敲詐 SQL 注入的潛力,但這種方法將盡可能地鎖定它。因為我倉促地輸入了這個,這裡也是一個例子,希望它能更好地展示這個方法:
-- CREATE THIS PROCEDURE USING AN ACCOUNT THAT HAS SUFFICIENT ACCESS TO THE DATA AND SP_SEND_DBMAIL CREATE PROCEDURE [dbo].[limited_sp_send_dbmail] @messageBody NVARCHAR(MAX) , @recipientList VARCHAR(MAX) , @reply_to_address VARCHAR(MAX) , @subject_line NVARCHAR(255) WITH EXECUTE AS SELF AS -- does not allow the usage of @query parameter EXEC msdb.dbo.sp_send_dbmail @profile_name='MyDBMailProfile' , @recipients = @recipientList , @reply_to = @reply_to_address , @subject = @subject_line , @body = @messageBody GO EXECUTE [limited_sp_send_dbmail] @messageBody = N'Hello World!', @recipientList = 'john.eisbrener@Contoso.com', @reply_to_address = 'john.eisbrener@Contoso.com', @subject_line = N'Hello World!' GO Mail (Id: 36757) queued.