Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架数据库的SQL注入。SqlQuery_C#_Sql Server_Asp.net Mvc_Entity Framework_Sql Injection - Fatal编程技术网

C# 实体框架数据库的SQL注入。SqlQuery

C# 实体框架数据库的SQL注入。SqlQuery,c#,sql-server,asp.net-mvc,entity-framework,sql-injection,C#,Sql Server,Asp.net Mvc,Entity Framework,Sql Injection,在我的项目中,我使用下面的示例代码定义了一个存储过程: 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 * FR

在我的项目中,我使用下面的示例代码定义了一个存储过程:

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();

如何使用实体框架防止这种情况发生?

您正在创建一个动态查询,其中连接了参数。这引起了问题

不要使用动态查询或验证参数(如果它包含任何关键字或字符)

您还可以根据参数将查询重写为IF-ELSE结构,因此不需要动态查询。

您不能 底层SQL过程有故障,是一场安全噩梦。你无法在它上面的图层上修复它。您在EntityFramework中已经尽了最大努力,但它仍然不安全。您需要修复该问题(SQL proc),而不是对使用它的层应用band aids



对于需要使用动态SQL和绑定参数的过程来说,这似乎是一个很好的起点。

为了避免/最小化SQL注入的风险,Microsoft提供了一些规则:

例如:

“切勿直接从用户输入生成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 C=@prmC'
    END 

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

sp_executesql的参考资料:

我建议您避免SQL语句中所有形式的字符串连接,即使在存储过程中也是如此。此外,您可以通过过滤单词来清理输入,以便在执行查询之前在EF端删除这些SQL关键字。可能我认为您无法用EF本身来防止这种情况。我会考虑看更大的图片,为什么你使用这样的存储过程,而不是让EF产生一个安全的查询?如果
Table
映射到一个实体,为什么不编写一个EF查询来返回它,根据需要使用不同的
Where()
子句?@Marco您想做什么?为什么不在LINQ中编写一个简单的
context.Entities.Where(条件1)
context.Entities.Where(条件2)
?甚至
var query=context.Entities.Where(条件1);query=query.Where(condition2)
如果要动态添加多个条件?谢谢您的回答,但我无法重写存储过程。有防止Sql注入的库吗?我可以使用正则表达式验证输入参数吗?@Marco您的存储过程本身就是SQL注入。你得把它放下。再多的黑客攻击(这就是那些“净化”库)也不能保证它的安全。当您有EF时,为什么要尝试使用存储过程?EF和LINQ已经允许您指定标准dynamically@Marco不。你可以应用各种各样的创可贴来确保你的参数不包含SQL代码,但最终,这是一场军备竞赛。您将始终落后一步并不断更新。这是一个示例。真正的存储过程使用大数据集,性能优于EF query。无论是谁负责该过程,请以
D'Artagnan
作为姓氏调用该过程,并针对其错误追踪器提出错误。
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 C=@prmC'
    END 

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