这种构建动态SQL的方法容易受到SQL注入的影响还是对性能不利?

这种构建动态SQL的方法容易受到SQL注入的影响还是对性能不利?,sql,performance,security,dynamic-sql,Sql,Performance,Security,Dynamic Sql,我想构建一个安全的动态select语句,它可以处理多个WHERE子句 例如,基本SQL看起来像: SELECT * FROM Books Where Type='Novel' 我将传递函数,如下所示: SafeDynamicSQL("author,=,Herman Melville","pages,>,1000"); 这将清理输入并连接,如: SELECT * FROM Books Where Type='Novel' AND author=@author AND pages>@

我想构建一个安全的动态select语句,它可以处理多个WHERE子句

例如,基本SQL看起来像:

SELECT * FROM Books Where Type='Novel'
我将传递函数,如下所示:

SafeDynamicSQL("author,=,Herman Melville","pages,>,1000");
这将清理输入并连接,如:

SELECT * FROM Books Where Type='Novel' AND author=@author AND pages>@pages

该函数将通过检查预定义列名数组来清理列名。操作符只能是>,看起来您正在重新设计任何数量的现有ORM解决方案,这些解决方案为创建WHERE子句提供了类似的API

您的问题的答案取决于您所说的“值将作为普通参数添加”是什么意思。如果您的意思是执行字符串连接以生成所显示的字符串,那么是的,这仍然会受到SQL注入攻击。如果您的意思是使用实际的参数化查询,那么您将是安全的。在后一种情况下,您将生成以下内容

 SELECT * FROM Books Where Type='Novel' AND author=? AND pages > ?
然后将其绑定到一个值列表,如['Herman Melville',1000]。它的确切外观取决于您使用的编程语言


最后,如果您采用这种方法,我强烈建议您将逗号分隔的参数改为三个独立的参数,这样可以节省大量的编程时间。

从安全角度来看,几乎任何附加(或插入)字符串以创建SQL的代码都是不好的形式,并且可能受到一些SQL攻击向量的影响。仅使用边界参数,避免整个问题;避免SQL注入非常简单。

感谢您的建议。你是对的,我忘了在我的示例中输入参数化值。我更喜欢codegens,这就是我在这里重新发明轮子的原因。