在带有文本参数的存储过程中是否可以进行sql注入?

我在我的存储过程中使用这样的查询

SET @Statement = 'SELECT Id,Title,Content,Status,ROW_NUMBER() OVER (ORDER BY ' + @Sort + ') AS StudentReport FROM YearBook WHERE ' + @Criteria + ') AS ArticleNumber WHERE StudentReport> ' + CONVERT(NVARCHAR, @StartRowIndex) + ' AND StudentReport<= (' + CONVERT(NVARCHAR, @StartRowIndex + @MaximumRows); 

只是想知道是否可以对这个存储过程进行sql注入。 如果是的话,我该如何预防呢? 需要帮忙 !!!

是的,这是可能的。 很简单,甚至。 尝试设置

 @Criteria = "\r\nGO\r\nexec sp_addlogin 'hacker', 'broken'\r\nGO"; 

批处理会产生错误,但介于两者之间的部分会运行,所以欢迎您的新登录。


执行查询的正确方法可能是这样的。

 CREATE PROC FindSomething @StartRowIndex int, @MaximumRows int, @Sort int, -- 1-4 representing the columns, say in a dropdown @Id int, @Content varchar(max), @Title varchar(max), @Status int AS SELECT Id,Title,Content,Status FROM ( SELECT Id,Title,Content,Status, ROW_NUMBER() OVER (ORDER BY CASE when @Sort = 1 then Id when @Sort = 4 then Status end, CASE when @sort = 2 then Title when @sort = 3 then Content end) AS StudentReport FROM YearBook WHERE (@id is null or @id = Id) AND (@Content is null or @Content = Content) AND (@Title is null or @Title = Title) AND (@status is null or @Status = Status) ) Numbered WHERE StudentReport >= @StartRowIndex AND StudentReport <= @StartRowIndex + @MaximumRows OPTION (RECOMPILE); GO 

在此处阅读有关动态搜索的更多信息: http://www.sommarskog.se/dyn-search.html

注意:我在排序中拆分了1/4和2/3,因为CASE语句的每个分支必须生成相同的类型,或者兼容。 int / varchar是一个非常糟糕的混合,在case语句中。

假设上面是您正在构建的字符串,然后使用EXECsp_executesql执行,那么可以使用SQL注入。

如何预防它取决于你想要做什么。 也许你需要重新思考你的方法。

是的,它会的。 你仍然可以做些事来帮助防御它

例如, @Sort是一个列名,所以你可以正确地逃避它(并确保如果有人试图注入某些东西,它将无法正常工作,因为它已被正确转义。为此使用QUOTENAME 。

 QUOTENAME(@Sort) 

@Criteria更加困难,因为您实际上期望SQL代码上有一个片段,因此很难找出有效和恶意的内容。 您可能想重新考虑一下您在这里尝试做什么。 如果必须使用Criteria,请确保已设置安全模型,以便只有绝对需要它的应用程序才能访问执行此操作的存储过程。 确保在发送SQL之前在应用程序中进行validation,以确保它所做的任何事情都不会造成损害。

看起来您正在尝试使用分页创建一个非常通用的搜索存储过程。 这些很难在t-sql中正确实现,并且由于分支逻辑或您需要添加的其他支持存储过程,可能会成为未来的维护难题……

我会开始看一下纯sql方法之外的其他选项。 使用orm或micro orm可以提供很多帮助。 实际上,看看Sam Saffron想出了什么……

http://samsaffron.com/archive/2011/09/05/Digging+ourselves+out+of+the+mess+Linq-2-SQL+created