sql-server – 为什么在存储过程中的此查询中不会发生SQL注入?
我做了以下存储过程: ALTER PROCEDURE usp_actorBirthdays (@nameString nvarchar(100),@actorgender nvarchar(100)) AS SELECT ActorDOB,ActorName FROM tblActor WHERE ActorName LIKE '%' + @nameString + '%' AND ActorGender = @actorgender 现在,我尝试做这样的事情.也许我做错了,但我想确保这样的过程可以阻止任何SQL注入: EXEC usp_actorBirthdays 'Tom','Male; DROP TABLE tblActor' 下图显示了在SSMS中执行的上述SQL,并且结果正确显示而不是错误: 顺便说一句,我在查询完成执行后添加了分号后面的部分.然后我再次执行它,但是当我检查表tblActor是否存在时,它仍然存在.难道我做错了什么?或者这真的是防注射吗?我想我在这里要问的是,这是一个像这样安全的存储过程吗?谢谢. 解决方法此代码正常工作,因为它是:>参数化,和 为了使SQL注入工作,您必须构建一个查询字符串(您没有这样做),而不是将单个撇号(‘)转换为转义撇号(”)(通过输入参数转义). 在你试图传递“妥协”价值时,’男性; DROP TABLE tblActor’字符串只是一个普通的字符串. 现在,如果你正在做的事情: DECLARE @SQL NVARCHAR(MAX); SET @SQL = N'SELECT fields FROM table WHERE field23 = ' + @InputParam; EXEC(@SQL); 然后,这将容易受到SQL注入,因为该查询不在当前的预解析上下文中;该查询目前只是另一个字符串.所以@InputParam的价值可能是’2015-10-31′; SELECT * FROM PlainTextCreditCardInfo;这可能会产生问题,因为该查询将被呈现并执行,如下所示: SELECT fields FROM table WHERE field23 = '2015-10-31'; SELECT * FROM PlainTextCreditCardInfo; 这是使用存储过程的一个(几个)主要原因:本质上更安全(好吧,只要你不通过构建像我上面所示的查询而不验证所使用的任何参数的值来规避安全性).虽然如果需要构建动态SQL,首选方法是使用sp_executesql对其进行参数化: DECLARE @SQL NVARCHAR(MAX); SET @SQL = N'SELECT fields FROM table WHERE field23 = @SomeDate_tmp'; EXEC sp_executesql @SQL,N'SomeDate_tmp DATETIME',@SomeDate_tmp = @InputParam; 使用这种方法,有人试图传递’2015-10-31′; SELECT * FROM PlainTextCreditCardInfo;对于DATETIME输入参数,在执行存储过程时会出错.或者即使存储过程接受@InputParameter作为NVARCHAR(100),它也必须转换为DATETIME才能传入sp_executesql调用.即使动态SQL中的参数是字符串类型,首先进入存储过程,任何单个撇号都会自动转义为双撇号. 有一种鲜为人知的攻击类型,攻击者试图用撇号填充输入字段,以便存储过程内部用于构造动态SQL但声明太小的字符串不能适合所有内容并推出结束的撇号,并以某种方式最终得到正确数量的撇号,以便不再在字符串中“转义”.这被称为SQL截断,并在MSDN杂志文章“新SQL截断攻击和如何避免它们”中进行了讨论,但该文章已不再在线.它 – 2006年11月版的MSDN杂志 – 仅在存档文件中提供(.chm格式): 有关SQL注入(包括各种RDBMS和方案)的更多详细信息,请参阅Open Web Application Security Project(OWASP)中的以下内容: SQL注入和SQL截断的相关堆栈溢出答案: (编辑:威海站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |