Sql server 当t-sql动态代码作为过滤器使用sp_executesql时,保护它的最佳方法是什么
我正在制作一个接受动态过滤的存储过程,问题是我需要尽可能地保持它的灵活性Sql server 当t-sql动态代码作为过滤器使用sp_executesql时,保护它的最佳方法是什么,sql-server,tsql,sql-injection,dynamic-sql,Sql Server,Tsql,Sql Injection,Dynamic Sql,我正在制作一个接受动态过滤的存储过程,问题是我需要尽可能地保持它的灵活性 ALTER PROCEDURE astp_test @WhereClause NVARCHAR(max) = NULL AS DECLARE @FilteredResults AS TABLE (testId int, testfield datetime2) DECLARE @sql AS NVARCHAR(MAX) = N'SELECT testId ,
ALTER PROCEDURE astp_test
@WhereClause NVARCHAR(max) = NULL
AS
DECLARE @FilteredResults AS TABLE (testId int, testfield datetime2)
DECLARE @sql AS NVARCHAR(MAX) = N'SELECT testId , testfield
FROM aviw_test
WHERE IsOpen = 1 AND IsLatesInsert = 1
AND testStepNo = 7
AND test2 IS NULL
AND (testfielddate IS NULL OR testfielddate2 < GETUTCDATE())
AND Domain IN (SELECT Domain FROM project WITH (NOLOCK) WHERE Status = ''Active'')' +
CASE WHEN @WhereClause IS NOT NULL
THEN N' AND ' + @WhereClause ELSE N''
END
INSERT INTO @FilteredResults
EXEC sys.sp_executesql @stmt = @sql;
我希望以这种方式保护@WhereClause输入,因为有一些复选框发送如下内容:testDatePick='2019-10-10'和testStage='InProgress'和testArea='London'。那么什么是最好的方法呢?请尝试下面的方法
ALTER PROCEDURE astp_test
@WhereClause NVARCHAR(max) = NULL
AS
DECLARE @FilteredResults AS TABLE (testId int, testfield datetime2)
DECLARE @sql AS NVARCHAR(MAX) = N'SELECT testId , testfield
FROM aviw_test
WHERE IsOpen = 1 AND IsLatesInsert = 1
AND testStepNo = 7
AND test2 IS NULL
AND (testfielddate IS NULL OR testfielddate2 < GETUTCDATE())
AND Domain IN (SELECT Domain FROM project WITH (NOLOCK) WHERE Status = ''Active'')'
if @WhereClause is not null
set @sql=@sql + 'AND ' + @WhereClause
INSERT INTO @FilteredResults
EXEC sys.sp_executesql @stmt = @sql;
如果您有任何问题,请告诉我
谢谢最好的方法是不要使用动态sql。@where子句包含什么?为什么不使用ORM生成一个好的SQL查询?事实上,为什么不将@sql转换成一个视图并在其上编写一个简单的查询呢?带NOLOCK的PS不会使缓慢的查询运行得更快,它会在获取额外锁的同时读取脏数据。为了使这个子查询运行得更快,请在Status、Domain上添加一个索引,并可能使用SNAPSHOT isolationI不同意@PanagiotisKanavos。但是,最好的方法是使用QUOTENAME安全地注入对象名,并对语句进行参数化。但是,在何处注入一个WHERE是完全错误的想法,因为你永远无法保证它的安全;您必须信任客户端,因为在T-SQL中解析T-SQL是不可能的。在这种情况下,最好将查询逻辑集中在客户机中,这样您就有一个地方来验证它,并为查询中不会更改的部分声明一个视图。我还建议阅读大量关于不同的、更安全的动态搜索方法的背景信息,以及与每种方法相关的陷阱。我不同意这种笼统的说法,最好的方法是不要使用动态sql@PanagiotisKanavos。该评论自发布以来一直在编辑,但仅仅说动态SQL不好肯定是错误的。写得不好的动态SQL是不好的,但写得好、安全的动态SQL是好的;当然,它也有使用的时间。为了修复它的安全性,@pixe您需要删除该参数@WhereClause,并将其替换为需要比较的每列1个参数。这将需要对数据库和应用程序进行更改。这是一项要求。如果不这样做,就无法保证安全。如果您不能做到这一点,我强烈建议您删除该功能。