参数化查询如何帮助防止 SQL 注入?

新手上路,请多包涵

在查询 1 和 2 中,文本框中的文本都插入到数据库中。这里参数化查询有什么意义?

  1. 传递 txtTagNumber 作为查询参数
   SqlCommand cmd = new SqlCommand("INSERT INTO dbo.Cars " +"VALUES(@TagNbr);" , conn);
   cmd.Parameters.Add("@TagNbr", SqlDbType.Int);
   cmd.Parameters["@TagNbr"].Value = txtTagNumber.Text;

  1. 在构造查询之前将 txtTagNumber 转换为整数
   int tagnumber = txtTagNumber.Text.ToInt16(); /* EDITED */
   INSERT into Cars values(tagnumber.Text); /* then is it the same? */

另外,在这里我将使用正则表达式验证来停止插入非法字符。

原文由 sqlchild 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 670
2 个回答

参数化查询在运行 SQL 查询之前会正确替换参数。它完全消除了“脏”输入改变查询含义的可能性。也就是说,如果输入包含 SQL,它就不能成为执行内容的一部分,因为 SQL 从未注入到结果语句中。

原文由 OJ. 发布,翻译遵循 CC BY-SA 4.0 许可协议

想象一个动态 SQL 查询

sqlQuery='SELECT * FROM custTable WHERE User=' + Username + ' AND
Pass=' + password

所以一个简单的 sql 注入只需将用户名放入 ' 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”, 用户名) parameters.add(“Pass”, 密码)

其中用户名和密码是指向相关输入用户名和密码的变量

现在,您可能会想,这根本不会改变任何事情。当然,您仍然可以在用户名字段中输入“Nobody OR 1=1’–”之类的内容,从而有效地进行查询:

 sqlQuery='SELECT * FROM custTable WHERE User=Nobody OR 1=1'-- AND
Pass=?'

这似乎是一个有效的论点。但是,你错了。

参数化查询的工作方式是将 sqlQuery 作为查询发送,并且数据库确切地知道该查询将做什么,然后才将用户名和密码仅作为值插入。这意味着它们不能影响查询,因为数据库已经知道查询会做什么。所以在这种情况下,它会查找 "Nobody OR 1=1'--" 的用户名和一个空白密码,这应该是错误的。

资料来源:lavamunky.com; 2011 年 11 月

原文由 user2156081 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进