将 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由单引号、双引号和加号绑定。
有人可以为我破译这个吗? 我将不胜感激。
谁教了你这个语法,谁就真的教了你一个错误的东西。
正如您所猜测的,此语法将字符串的内容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 语句(本身只是字符串)时,永远不应该使用它,因为这使用户能够传入一个字符串,让他们对数据库执行更具破坏性的语句。