参数是否足以防止Sql注入?
我一直在向我的同事以及在这里讲讲在SQL查询中使用参数的好处,尤其是在.NET应用程序中。 我甚至已经承诺给予他们针对SQL注入攻击的豁免权。
但我开始怀疑这是否属实。 是否有任何已知的SQL注入攻击会对参数化查询成功? 你可以例如发送一个字符串,导致服务器上的缓冲区溢出?
当然,为了确保Web应用程序的安全性(如清理用户输入和所有这些内容)还需要做其他考虑,但现在我正在考虑SQL注入。 我特别感兴趣的是对MsSQL 2005和2008的攻击,因为它们是我的主数据库,但所有数据库都很有趣。
编辑:澄清我的意思是参数和参数化查询。 通过使用参数我的意思是使用“变量”,而不是在字符串中构建sql查询。
所以不要这样做:
SELECT * FROM Table WHERE Name = 'a name'
我们这样做:
SELECT * FROM Table WHERE Name = @Name
然后在查询/命令对象上设置@Name参数的值。
占位符足以防止注入。 您可能仍然对缓冲区溢出持开放态度,但这是与SQL注入完全不同的攻击风格(攻击向量不是SQL语法,而是二进制文件)。 由于传递的参数都将被正确转义,因此攻击者无法通过将被视为“实时”SQL的数据。
您不能使用占位符内的函数,也不能使用占位符作为列名或表名,因为它们被转义并引用为字符串文字。
但是,如果在动态查询中使用参数作为字符串连接的一部分,则仍然容易受到注入的影响,因为您的字符串不会被转义,而是字面上的。 使用其他类型的参数(如整数)是安全的。
也就是说,如果您使用use input来设置security_level
之类的值,那么有人可以让自己成为系统中的管理员并拥有免费的所有权。 但这只是基本的输入验证,并且与SQL注入无关。
不,每次将未验证的数据插入到SQL查询中时,仍然存在SQL注入的风险。
通过从SQL语法中分离字面值,查询参数有助于避免此风险。
'SELECT * FROM mytable WHERE colname = ?'
这很好,但还有其他目的是将数据插入到不能使用查询参数的动态SQL查询中,因为它不是SQL值,而是表名,列名称,表达式或其他语法。
'SELECT * FROM ' + @tablename + ' WHERE colname IN (' + @comma_list + ')'
' ORDER BY ' + @colname'
无论您是使用存储过程还是直接从应用程序代码执行动态SQL查询都无关紧要。 风险依然存在。
这些案件的补救措施是根据需要聘请FIEO :
过滤器输入:在插入它们之前验证数据看起来像合法整数,表名,列名等。
转义输出:在这种情况下,“输出”意味着将数据放入SQL查询中。 我们使用函数来转换在SQL表达式中用作字符串文字的变量,以便字符串中的引号和其他特殊字符被转义。 我们还应该使用函数来转换将用作表名,列名等的变量。至于其他语法,例如动态地编写整个SQL表达式,这是一个更复杂的问题。
在这个线程中似乎有一些关于“参数化查询”定义的混淆。
鉴于以前的定义,许多链接显示工作攻击。
但“正常”的定义是后者。 鉴于这个定义,我不知道任何SQL注入攻击都可以工作。 这并不意味着没有一个,但我还没有看到它。
从评论中,我没有足够清楚地表达自己,所以这里有一个希望更清晰的例子:
这种方法适用于SQL注入
exec dbo.MyStoredProc 'DodgyText'
这种方法不适用于SQL注入
using (SqlCommand cmd = new SqlCommand("dbo.MyStoredProc", testConnection))
{
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter newParam = new SqlParameter(paramName, SqlDbType.Varchar);
newParam.Value = "DodgyText";
.....
cmd.Parameters.Add(newParam);
.....
cmd.ExecuteNonQuery();
}
链接地址: http://www.djcxy.com/p/16801.html
上一篇: Are Parameters really enough to prevent Sql injections?
下一篇: Do I have to guard against SQL injection if I used a dropdown?