2017-05-29 79 views
1

在項目中,我定義的存儲過程以下示例代碼:SQL注入實體框架Database.SqlQuery

CREATE PROCEDURE [dbo].[Stored] 
    @ParameterA AS varchar(128), 
    @ParameterB AS varchar(128), 
    @ParameterC AS varchar(400) 
AS 
BEGIN 
    DECLARE @query AS Varchar(MAX) 

    SET @query = 'SELECT * 
        FROM Table 
        WHERE A = '''+ @ParameterA + '' 

    IF @ParameterB = 'B' 
    BEGIN 
     SET @query = @query + ' AND C=''' + @ParameterC + '' 
    END 

    EXECUTE sp_executesql @query 
END 

我打電話實體框架此過程中通過下面的代碼:

DBContext.Database.SqlQuery<Object>("Stored", 
new SqlParameter("@p0", Param0), 
new SqlParameter("@p1", Param1), 
new SqlParameter("@p2", Param2)).ToList(); 

如果我把下面的字符串存儲過程,我產生一個SQL注入:

Param2 = "ABC' ; DROP TABLE Table2" 

我如何使用實體框架來防止這種情況?

+0

我建議你避免在SQL語句的字符串連接的所有形式,甚至在存儲過程中。另外,您可以通過過濾單詞來對輸入進行清理,以便在執行查詢之前在EF端刪除這些SQL關鍵字。 –

+0

可能[相關](https://stackoverflow.com/a/15941731/1154184) – Reyno

+0

我認爲你不能阻止EF本身的這種事情。我會考慮查看更大的圖片https://msdn.microsoft.com/zh-cn/library/cc716760(v=vs.110).aspx – Edgaras

回答

0

您正在創建一個動態查詢,在這裏您串聯參數。這是造成問題。

不使用動態查詢,或驗證參數(如果它包含的關鍵字或字符)

你也可以重寫查詢到的參數基礎IF-ELSE結構,所以你不需要動態查詢。

1

你不能

底層的SQL過程是錯誤的和安全的噩夢。你無法修復它上面的圖層。您在EntityFramework中盡力做到最好,但仍然不安全。您需要修復問題(SQL proc),並且不會將band幫助應用於使用它的圖層。


sp_executesql對於需要動態SQL和綁定參數的過程似乎是一個很好的起點。

+0

感謝您的回答,但我無法重寫我的存儲過程。 有一個庫可以防止Sql注入? 我可以使用正則表達式來驗證輸入參數嗎? – Marco

+0

@Marco你的存儲過程本身就是SQL注入。你將不得不放棄它。沒有任何黑客行爲(這就是那些「衛生消毒」庫)將使其安全。當你有EF時,你爲什麼試圖使用存儲過程? EF和LINQ已經允許你動態地指定標準 –

+0

@Marco **否**。你可以應用各種樂隊幫助,以確保你的參數不包含SQL代碼,但最終,這是一場軍備競賽。你總是會落後並不斷更新。 – nvoigt

2

有來自微軟的一些規則,以避免/最小化的SQL注入這裏的風險[]:https://docs.microsoft.com/en-us/sql/relational-databases/security/sql-injection

例如:

「從來沒有建立直接從用戶輸入的Transact-SQL語句「。

這意味着在這種情況下,我會使用參數sp_executesql改寫原代碼:

CREATE PROCEDURE [dbo].[Stored] 
    @ParameterA AS varchar(128), 
    @ParameterB AS varchar(128), 
    @ParameterC AS varchar(400) 
AS 
BEGIN 
    DECLARE @query AS Varchar(MAX) 

    SET @query = 'SELECT * 
        FROM Table 
        WHERE A = @prmA' 

    IF @ParameterB = 'B' 
    BEGIN 
     SET @query = @query + ' AND [email protected]' 
    END 

    EXECUTE sp_executesql @query, N'@prmA VARCHAR(128), @prmC VARCHAR(128)', @prmA = @ParameterA, @prmC = @ParameterC 
END 

參考爲sp_executesql的:https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-executesql-transact-sql