Run*_*tad 82 sql database asp.net sql-injection
我一直在向我的同事们讲道,在这里谈论在SQL查询中使用参数的好处,特别是在.NET应用程序中.我甚至承诺给予他们免受SQL注入攻击的抵抗力.
但我开始怀疑这是否真的如此.是否有任何已知的SQL注入攻击可以成功对抗参数化查询?例如,您可以发送一个导致服务器缓冲区溢出的字符串吗?
当然还有其他考虑因素可以确保Web应用程序是安全的(比如清理用户输入和所有内容),但现在我正在考虑SQL注入.我对MsSQL 2005和2008的攻击特别感兴趣,因为它们是我的主要数据库,但所有数据库都很有趣.
编辑:澄清参数和参数化查询的含义.通过使用参数我的意思是使用"变量"而不是在字符串中构建SQL查询.
所以不要这样做:
SELECT * FROM Table WHERE Name = 'a name'
Run Code Online (Sandbox Code Playgroud)
我们这样做:
SELECT * FROM Table WHERE Name = @Name
Run Code Online (Sandbox Code Playgroud)
然后在查询/命令对象上设置@Name参数的值.
Ada*_*ire 49
占位符足以防止注射.您可能仍然对缓冲区溢出持开放态度,但这与SQL注入的攻击风格完全不同(攻击向量不是SQL语法,而是二进制).由于传递的参数都将被正确转义,因此攻击者无法传递将被视为"实时"SQL的数据.
您不能在占位符中使用函数,也不能将占位符用作列名或表名,因为它们会被转义并作为字符串文字引用.
但是,如果在动态查询中使用参数作为字符串连接的一部分,则仍然容易受到注入,因为您的字符串不会被转义,而是字面上的.使用其他类型的参数(例如整数)是安全的.
也就是说,如果你使用使用输入来设置类似的值security_level,那么有人可以让自己成为系统中的管理员并拥有一个免费的所有人.但这只是基本的输入验证,与SQL注入无关.
Bil*_*win 13
不,只要将未经验证的数据插入到SQL查询中,就仍然存在SQL注入的风险.
查询参数通过将文字值与SQL语法分开来帮助避免此风险.
'SELECT * FROM mytable WHERE colname = ?'
Run Code Online (Sandbox Code Playgroud)
这很好,但还有其他目的是将数据插入到不能使用查询参数的动态SQL查询中,因为它不是SQL值,而是表名,列名,表达式或其他语法.
'SELECT * FROM ' + @tablename + ' WHERE colname IN (' + @comma_list + ')'
' ORDER BY ' + @colname'
Run Code Online (Sandbox Code Playgroud)
无论您是使用存储过程还是直接从应用程序代码执行动态SQL查询,都无关紧要.风险仍然存在.
在这些情况下的补救措施是根据需要使用FIEO:
过滤器输入:在插入数据之前,验证数据看起来像合法的整数,表名,列名等.
转义输出:在这种情况下,"输出"表示将数据放入SQL查询.我们使用函数来转换在SQL表达式中用作字符串文字的变量,以便对字符串中的引号和其他特殊字符进行转义.我们还应该使用函数来转换将用作表名,列名等的变量.至于其他语法,比如动态编写整个SQL表达式,这是一个更复杂的问题.
Roa*_*ior 12
在这个线程中似乎有一些关于"参数化查询"定义的混淆.
鉴于以前的定义,许多链接显示了工作攻击.
但"正常"定义是后者.鉴于该定义,我不知道任何SQL注入攻击将起作用.这并不意味着没有一个,但我还没有看到它.
从评论中,我并没有足够清楚地表达自己,所以这里有一个希望更清晰的例子:
这种方法是打开SQL注入
exec dbo.MyStoredProc 'DodgyText'
Run Code Online (Sandbox Code Playgroud)
这种方法不适用于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();
}
Run Code Online (Sandbox Code Playgroud)
Ste*_*owe 10
用于构造动态查询的字符串类型(varchar,nvarchar等)的任何sql参数仍然容易受到攻击
否则参数类型转换(例如int,decimal,date等)应该消除任何通过参数注入sql的尝试
编辑:一个例子,其中参数@ p1是一个表名
create procedure dbo.uspBeAfraidBeVeryAfraid ( @p1 varchar(64) )
AS
SET NOCOUNT ON
declare @sql varchar(512)
set @sql = 'select * from ' + @p1
exec(@sql)
GO
Run Code Online (Sandbox Code Playgroud)
如果从下拉列表中选择@ p1,则它是潜在的sql-injection攻击向量;
如果@ p1是以编程方式制定的,没有用户干预的能力那么它就不是潜在的sql-injection攻击向量