将SQL Server SQL语句注入c#代码的语法

时间:2016-01-22 20:18:27

标签: c# sql sql-server ado.net

我有这个c#代码,用ADO.NET从SQL Server数据库中检索数据:

//Define ADO.NET objects
    string selectSQL;
    selectSQL = "SELECT * FROM slip ";
    selectSQL += "WHERE slip_id='" + txtSlipID_srch + "'";

我已经阅读了一本书中的语法并且在大学时已经给出了语法,但除了“它是语法”之外,我还没有给出解释。我在谈论以下语法:

'" + txtSlipID_srch + "'

即字段名称txtSlipID_srch由单引号,双引号和加号绑定。

有人可以为我解读这个吗?我很感激。

4 个答案:

答案 0 :(得分:1)

无论是谁教过你这种语法,都会教你一个错误的东西 正如您所猜测的,此语法将字符串txtSlipID_srch的内容与您的SQL文本连接,从而形成来自固定文本和可变部分的完整指令。然后将整个内容传递给数据库引擎以执行。

但是允许用户在文本框中键入内容然后使用该输入来构建SQL查询实际上是错误的

用户可以键入任何内容,并且任何内容都可能是一个伪造的字符串,它会改变您的意图并破坏您的数据库或获取您不希望他看到的信息(密码或信用卡号)。它被称为Sql Injection,有数千篇关于如何实现这种黑客技术的文章。我不想重复任何事情,您只需查看well known comics+question+answers并阅读下面的解释

除此之外。存在正确解析字符串的问题。字符串变量中存在单引号将使查询无效,因为单引号用于分隔传递给数据库的字符串值。使用转换过程应在字符串中转换的小数和日期也是如此。在这里你应该为数据库创建正确的文本(它是否像逗号或小数点?,日期的格式是' dd / MM / yyyy'或者' MM / dd / yyyy& #39;或者什么?依此类推)

唯一有效的方法是使用参数化查询,以这种方式编写命令文本

selectSQL = "SELECT * FROM slip WHERE slip_id=@id";

现在不再有两个字符串的串联,并且字符串值周围没有单引号来逃避'它们,但只是一个名为@id的参数占位符。

ADO.NET库将提供适当的类来处理该参数,将值传递给数据库引擎,以便正确处理它。

SqlCommand cmd = new SqlCommand(selectSQL, connection);
cmd.Parameters.Add("@id", SqlDbType.NVarChar).Value = txtSlipID_srch;
SqlDataReader reader = cmd.ExecuteReader();
...... 

答案 1 :(得分:0)

因为您希望生成的SQL看起来像这样:

SELECT * FROM slip WHERE slip_id='somevalue'

它需要生成的SQL语句中的单引号。

双引号用于定义C#代码中的字符串。 单引号用于在SQL语句中定义字符串。

答案 2 :(得分:0)

使用单引号的原因是因为SQL期望字符串值用单引号括起来。 (如其他答案中所述)

但是不使用字符串连接来创建SQL查询。您的输入可能来自用户,任何恶意用户都可以利用它。阅读SQL Injection

你可以用更好的方式做到这一点:

使用参数

using (SqlConnection conn = new SqlConnection("connection string"))
using (SqlCommand cmd = new SqlCommand("SELECT * FROM slip WHERE slip_id=@slipID", conn))
{
    cmd.Parameters.AddWithValue("@slipID", txtSlipID_srch);//Even use .Add and specify data type
    //open connection 
    //execute command
}

using statement在执行命令后处理资源。

(如果你的书之后没有提到使用parameters,那么没有那本书你会比较好,从其他地方读书)

答案 3 :(得分:0)

在这种情况下,+是一个连接运算符。在示例中,txtSlipID_srch是一个包含值的变量,您将该值连接到另一个字符串(即您的SQL语句)。就像我想说Hello Maarten你今天好吗?我会写SyntaxError: [macro] Macro `@` could not be matched with `name...` 57: console.log(@name); 。因此,当Maarten存储在yourNameVariable中时,它会获取该信息并将其与其他两个字符串连接起来。请注意我还必须包含空格以确保字符串正确显示?但是正如每个人都指出的那样,在构建sql语句(它们本身只是字符串)时永远不应该使用它,因为这使用户能够传入一个字符串,使它们能够对数据库执行更具破坏性的语句。