Sql-Server

我想知道 SQL Server 2012 是否保護 msdb.dbo.sp_send_dbmail 參數?

  • June 21, 2017

我使用這個系統儲存過程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 可以利用模擬(ref1ref2),然後您只需向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.

引用自:https://dba.stackexchange.com/questions/176902