【问题标题】:Why is concatenating SQL strings a bad idea?为什么连接 SQL 字符串是个坏主意?
【发布时间】:2014-06-04 10:49:46
【问题描述】:

我读过这样连接 SQL 字符串是个坏主意:

cmd.CommandText = "Insert INTO workers Values (" + User.Identity.Name + "," + WorkerName.Text + "," + GetUniqueWorkerKey() + ");";

所以推荐的方法是:

cmd.CommandText = "Insert INTO workers Values (@Username, @WorkerName, @WorkerKey)";
cmd.Parameters.AddWithValue("@Username", User.Identity.Name);
cmd.Paramters.AddWithValue("@WorkerName", TheWorkerNameYouPassedToThisMethod);

自从我读到它之后,我就一直在避免连接 SQL 字符串,但我从来没有真正知道不这样做的原因。 AddWithValue() 方法最终不会在幕后进行相同的字符串连接吗?

也许该方法会去除特殊字符并将字符转换为 html 实体以防止 sql 注入,但我可以在连接我的 SQL 之前完成所有这些操作,我也得到相同的效果,不是吗?还是有其他原因不练习 SQL 的字符串连接?

【问题讨论】:

  • @SriramSakthivel 参数化和连接有什么区别?参数化的不是在幕后进行字符串连接吗?如果是这样,同样的 sql 注入仍然是可能的。
  • @Carven 不,它将替换占位符中的值。它不会串联。如果您的参数值包含任何“sql 关键字”,它将不会被执行,而是会抛出异常。试试看..
  • @Carven: NO 参数化查询是 NOT 串联的“幕后” !” - 这就是重点。查询作为参数化查询与参数及其值一起发送到服务器 - 它在发送之前在客户端NOT连接在一起到服务器!然后只有服务器将获取这些参数并替换它们的值 - 并进行如下检查:这必须是一个有效的整数并拒绝任何试图偷偷不属于那里的东西

标签: c# sql .net concatenation string-concatenation


【解决方案1】:

简答:通过连接字符串构建查询通常允许 SQL 注入。

假设有人试图创建一个名为“Bob, Joe, 12345); DROP TABLE workers; --”的用户。您最终构建了查询“Insert INTO workers Values(Bob, Joe, 12345); DROP TABLE workers; --name, 34345236);”Bye-bye 数据库。 SQL 注入还可能导致查询返回不应返回的数据,例如密码表。只要您有 SQL 注入,就假设您允许任意第三方向您的数据库发出任意命令。

AddWithValue() 方法称为“参数化查询”。它会生成非常相似的命令,但 AddWithValue() 会处理任何奇怪的东西,例如参数值中的空格和引号,这些东西可能会导致命令的含义与您想要的含义不同。当然,您可以手动进行转义,但要正确进行可能会很棘手。让库为您处理会更容易、更安全。

Obligatory XKCD

请注意,我不是的意思是库实际上是在转义您在创建参数化查询时提供的字符串。 可以,但我不知道有任何 SQL 库采用这种方法——通常,SQL 引擎对参数化查询有特殊支持。这允许参数化查询比临时查询更有效:SQL 引擎可以预编译 SQL 语句,只留下要在运行时填写的字段值。

【讨论】:

    猜你喜欢
    • 2011-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-31
    • 1970-01-01
    • 1970-01-01
    • 2013-02-27
    相关资源
    最近更新 更多