究竟是什么在后台发生,使得SQLParameter阻止.NET参数化查询中的SQL Inection攻击?它只是剥离任何可疑角色还是还有其他功能?
有没有人检查过当您传递恶意输入时SQL Server的真正含义?
究竟是什么在后台发生,使得SQLParameter阻止.NET参数化查询中的SQL Inection攻击?它只是剥离任何可疑角色还是还有其他功能?
有没有人检查过当您传递恶意输入时SQL Server的真正含义?
Answers:
一个更容易理解和更一般的答案是这样的:
想象一下动态SQL查询:
sqlQuery='SELECT * FROM custTable WHERE User=' + Username + ' AND Pass=' + password
一个简单的SQL注入就是将Username输入为 ' OR 1=1--
这将有效地使SQL查询:
sqlQuery='SELECT * FROM custTable WHERE User='' OR 1=1-- ' AND PASS=' + password
这表示选择所有用户名为空(''
)或1=1
布尔值(等于true)的客户。然后,它--
用于注释掉其余的查询。因此,这将打印出整个客户表,或者使您能够使用它进行任何操作。
现在,参数化查询的方式有所不同,例如:
sqlQuery='SELECT * FROM custTable WHERE User=? AND Pass=?'
parameters.add("User", username)
parameters.add("Pass", password)
其中用户名和密码是指向关联的输入的用户名和密码的变量。
现在,您可能会认为,这根本不会改变任何东西。当然,您仍然可以将诸如Nobody OR 1 = 1'-之类的内容输入用户名字段,从而有效地进行查询:
sqlQuery='SELECT * FROM custTable WHERE User=Nobody OR 1=1'-- AND Pass=?'
这似乎是一个有效的论点。但是,你会错的。
参数化查询的工作方式是,将SQL查询作为查询发送,并且数据库确切知道此查询将执行的操作,然后才将用户名和密码仅作为值插入。这意味着它们不能影响查询,因为数据库已经知道查询将执行的操作。因此,在这种情况下,它将查找用户名Nobody OR 1=1'--
和空密码,该用户名应为false。
不过,这并不是一个完整的解决方案,因此仍然需要进行输入验证,因为这不会影响其他问题,例如 xss攻击,因为您仍然可以将javascript放入数据库中。然后,如果将其读出到页面上,则将根据任何输出验证将其显示为普通javascript。因此,实际上最好的办法仍然是使用输入验证,但是使用参数化查询或存储过程来停止任何SQL攻击。
资料来源:http://www.lavamunky.com/2011/11/why-parameterized-queries-stop-sql.html
“诸如SqlParameterCollection之类的参数集合提供类型检查和长度验证。如果使用参数集合,则将输入视为文字值,而SQL Server则不将其视为可执行代码。使用参数集合的另一个好处是,您可以可以执行类型和长度检查。超出范围的值会触发异常。这是深度防御的一个很好的例子。”
FROM
子句,来表示一个逗号的单个参数的在分隔的列表IN
子句等