我有一个存储过程,它返回网格控件的数据。给定表名称,网格将显示该表中的数据。用户可以对此数据进行排序和过滤。还有用于大型数据集的分页逻辑。
从运行时开始,不知道从中提取数据的表的名称,因此使用了动态SQL。这很好用,但很容易受到SQL注入的攻击 - tableName,sortExpression和filterExpression变量在客户端生成并传递给服务器。
以下是该程序的简化版本:
create procedure ReadTable (
@tableName as varchar(128),
@sortExpression as varchar(128),
@filterExpression as varchar(512)
)
as
begin
declare @SQLString as nvarchar(max) =
'select * from ' + @tableName +
' where ' + @filterExpression +
' order by ' + @sortExpression
exec Sp_executesql @SQLString
end
在这种情况下,我很难找到一种方法来轻松防止SQL注入。我找到了一个很好的答案,解释了如何检查@tableName是否合法(How should I pass a table name into a stored proc?),但该方法不适用于过滤或排序字符串。
在将数据传递到数据库之前,可能有一种方法是对服务器端进行一些清理 - 将表达式分解为列名,并根据表的已知列名检查它们。
会有更简单的方法吗?