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

本文关键字:SQL 代码 语法 注入 Server 语句 | 更新日期: 2023-09-27 18:31:39

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

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

我在一本书中读过语法,并在大学里得到了语法,但除了"这是语法"之外,我没有得到任何解释。 我说的是以下语法:

'" + txtSlipID_srch + "'

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

有人可以为我破译这个吗? 我将不胜感激。

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

谁教了你这个语法,谁就真的教了你一个错误的东西。
正如您所猜测的,此语法将字符串的内容txtSlipID_srch连接到 SQL 文本,形成来自固定文本和变量部分的完整指令。然后将整个事情传递给数据库引擎执行。

但是允许用户在文本框中键入某些内容,然后使用该输入来构建SQL查询确实是一件错误的事情。

用户可以键入任何内容,

并且任何内容也可能是伪造的字符串,可以更改您的意图并破坏您的数据库或获取您不希望他看到的信息(密码或信用卡号)。它被称为SQL注入,有数千篇关于如何实现这种黑客技术的文章。我不想重复任何事情,你可以简单地看看这个著名的漫画+问题+答案并阅读下面的解释

除此之外。存在正确解析字符串的问题。字符串变量中存在单引号将使查询无效,因为单引号用于分隔传递给数据库的字符串值。小数和日期也会发生同样的情况,这些小数和日期应该通过转换过程转换为字符串。同样在这里你应该为数据库创建正确的文本(它是否喜欢逗号或小数点?,日期的格式是"dd/MM/yyyy"或"MM/dd/yyyy"还是什么?等等)

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

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();
...... 

因为您希望生成的 SQL 如下所示:

SELECT * FROM slip WHERE slip_id='somevalue'

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

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

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

但不要使用字符串串联来创建 SQL 查询。您的输入可能来自用户,任何恶意用户都可以利用它。阅读有关 SQL 注入的信息。

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

使用参数

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语句,用于在执行命令后释放资源。

(另外,如果你的书没有提到以后使用parameters,那么你最好没有那本书,从其他地方阅读)

在这种情况下,+ 是一个串联运算符。在示例中,txtSlipID_srch是一个保存值的变量,您将该值连接成另一个字符串(即 SQL 语句)。就像我想说你好马丁,你今天好吗?我会写string greeting = "Hello " + yourNameVariable + " how are you today?";.因此,当 Maarten 存储在 yourNameVariable 中时,它会获取该信息并将其与其他两个字符串连接起来。请注意,我还必须包含空格以确保字符串正确显示?但正如大家所指出的,在构建 sql 语句(本身只是字符串)时,永远不应该使用它,因为这使用户能够传入一个字符串,让他们对数据库执行更具破坏性的语句。