参数化查询如何帮助防止 SQL 注入?
在查询 1 和 2 中,文本框中的文本都被插入到数据库中。这里参数化查询有什么意义呢?
将
txtTagNumber
作为查询参数传递SqlCommand cmd = new SqlCommand("INSERT INTO dbo.Cars " +"VALUES(@TagNbr);" , conn); cmd.Parameters.Add("@TagNbr", SqlDbType.Int); cmd.Parameters["@TagNbr"].Value = txtTagNumber.Text;
在构建查询之前将
txtTagNumber
转换为整数int tagnumber = txtTagNumber.Text.ToInt16(); /* 编辑 */ 插入汽车值(tagnumber.Text); /* 那么是一样的吗? */
另外,这里我将使用正则表达式验证来阻止插入非法字符。
In both queries 1 and 2, the text from the textbox is inserted into the database. What's the significance of the parameterized query here?
Passing
txtTagNumber
as a query parameterSqlCommand cmd = new SqlCommand("INSERT INTO dbo.Cars " +"VALUES(@TagNbr);" , conn); cmd.Parameters.Add("@TagNbr", SqlDbType.Int); cmd.Parameters["@TagNbr"].Value = txtTagNumber.Text;
Converting
txtTagNumber
to an integer before constructing the queryint tagnumber = txtTagNumber.Text.ToInt16(); /* EDITED */ INSERT into Cars values(tagnumber.Text); /* then is it the same? */
Also, here I would use Regular Expression validation to stop insertion of illegal characters.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
参数化查询在运行 SQL 查询之前对参数进行正确的替换。它完全消除了“脏”输入改变查询含义的可能性。也就是说,如果输入包含 SQL,它就不能成为执行内容的一部分,因为 SQL 永远不会注入到结果语句中。
Parameterized queries do proper substitution of arguments prior to running the SQL query. It completely removes the possibility of "dirty" input changing the meaning of your query. That is, if the input contains SQL, it can't become part of what is executed because the SQL is never injected into the resulting statement.
来源:lavamunky.com; 2011 年 11 月
Source: lavamunky.com; Nov 2011
当可能的参数中包含 SQL 并且字符串没有按应有的方式处理时,就会发生 SQL 注入,例如
:
并且条件是来自请求中的用户的字符串。如果条件是恶意的
例如:
您最终可能会运行恶意脚本。
但是,使用参数,输入将清除任何可能转义字符串字符的字符,这意味着您可以确保无论输入什么内容都将无法运行注入脚本。
使用带有参数的命令对象,实际执行的 SQL 看起来像这样:
本质上它将查找 rowname = a';drop table mytable where 1=1' 的行
并且不运行剩余的脚本。
SQL injection happens when a possible parameter has SQL within it and the strings are not handled as it should be
eg:
and the condition is a string coming from the user in the request. If condition is malicious
say eg:
you could end up running malicious scripts.
However, using parameters the input will be cleaned of any characters which might escape string characters, which means you can be ensured no matter what comes in it will not be able to run inject scripts.
Using the command object with parameters the SQL actually executed would look like this:
in essence it will be looking for a row with rowname = a';drop table mytable where 1=1'
and not running the remaining script.
参数化查询可以处理一切 - 为什么要这么麻烦呢?
通过参数化查询,除了一般注入之外,您还可以获得处理的所有数据类型、数字(int 和 float)、字符串(带有嵌入的引号)、日期和时间(当不调用 .ToString() 时,不会出现格式问题或本地化问题由于文化不变,您的客户转移到具有意外日期格式的机器)。
Parameterized queries handles everything - why go to the trouble?
With parametrized queries, in addition to general injection, you get all the data types handled, numbers (int and float), strings (with embedded quotes), dates and times (no formatting problems or localization issues when .ToString() is not called with the invariant culture and your client moves to a machine with and unexpected date format).
参数化查询允许客户端从查询文本中单独传递数据。
在大多数没有文本的地方,您可以进行验证+转义。
当然,参数化对于其他类型的注入没有帮助,但由于参数是单独传递的,因此它们不用作执行文本查询。
一个很好的类比是大多数现代处理器和操作系统使用的“最近”执行位,以防止缓冲区溢出。它仍然允许缓冲区溢出,但阻止注入数据的执行。
Parameterized queries allow the client to pass the data separately form the query text.
Where on most free from text you would do validation + escaping.
Of course Parameterization don't help against other kind of injection, but as the parameter are passed separately, they are not use as execution text query.
A good analogy would be the "recent" execution bit used with most of the modern processor and Operating system to protect from buffer overflow. It still allows the buffer overflow but prevent the execution of the injected data.
人们为什么会有这样的感觉是完全可以理解的。
vs
上面的两个查询似乎做了同样的事情,但实际上却没有。
前者使用输入进行查询,后者决定查询,但仅替换查询执行期间的输入。
更清楚地说,参数的值位于堆栈上存储变量内存的某个位置,并在需要时用于搜索。
因此,如果我们将
' OR '1'='1
作为用户名的输入,则前者将动态构造一个新的查询或作为 sql 查询的一部分的查询然后执行的字符串sqlQuery
。在同一输入上,后者将在
users
表的username
字段中搜索' OR '1'='
,并使用 静态在查询字符串sqlQuery
中指定查询只是为了巩固它,这是您使用参数进行查询的方式:
It is quite understandable why one would feel so.
vs
Both the above queries seem to do the same thing.But they actually don't.
The former uses input to for a query, the latter decides on the query but only substitutes the inputs as it is during the execution of the query.
To be more clear, the parameters' values are located some where on the stack where the variables' memory is stored and is used for search when needed.
So if we were to give
' OR '1'='1
as the input in username, the former would dynamically construct a new queries or queries as part of the sql query stringsqlQuery
which is then executed.While on the same input, latter would search for
' OR '1'='
in theusername
field of theusers
table with the statically specified query in the query stringsqlQuery
Just to consolidate it, this is how you use parameters to make query: