WPF/SQL:用参数替换值?



我是C#的新手,我写了以下代码。通读文档后,我意识到我的代码应该容易受到 SQL 注入的影响,因为我没有为我的值使用参数(据我了解,您可以通过search.Text注入不需要的查询(。我什至应该担心它,因为我基本上将我的值锁定在"引号内?

我在这里找到了一些方向,但我无法让它工作: 如何在 sql 语句中使用字符串变量

public void InvokeDataGridAddress()
{
switch (ComboBoxSelection.Text)
{
case "NASLOV":
comboBoxValue = "SELECT * FROM [cbu_naslovi] WHERE [ADDRESS] LIKE '%" + search.Text + "%' COLLATE Latin1_general_CI_AI";
break;
case "LASTNIK":
comboBoxValue = "SELECT [cbu_naslovi].* FROM [cbu_deli], [cbu_naslovi] WHERE [cbu_deli].LASTNIK LIKE '%" + search.Text + "%' COLLATE Latin1_general_CI_AI AND [cbu_deli].IDX = [cbu_naslovi].ID";
break;
case "OBJEKT":
comboBoxValue = "SELECT * FROM [cbu_naslovi] WHERE [SO] LIKE '%" + search.Text + "%'";
break;
case "PARCELA":
comboBoxValue = "SELECT * FROM [cbu_naslovi] WHERE [P1] LIKE '%" + search.Text + "%' OR [P2] LIKE '%" + search.Text + "%' OR [P3] LIKE '%" + search.Text + "%' OR [P4] LIKE '%" + search.Text + "%' OR [P5] LIKE '%" + search.Text + "%' OR [P6] LIKE '%" + search.Text + "%' OR [P7] LIKE '%" + search.Text + "%' OR [P8] LIKE '%" + search.Text + "%' OR [P9] LIKE '%" + search.Text + "%' OR [P10] LIKE '%" + search.Text + "%' OR [P11] LIKE '%" + search.Text + "%' OR [P12] LIKE '%" + search.Text + "%' OR [P13] LIKE '%" + search.Text + "%' OR [P14] LIKE '%" + search.Text + "%' OR [P15] LIKE '%" + search.Text + "%' OR [P16] LIKE '%" + search.Text + "%' OR [P17] LIKE '%" + search.Text + "%'";
break;
}
comboBoxValue = comboBoxValue + " ORDER BY [ULICA] ASC, [OBMOCJE] ASC, LEN ([HS]) ASC, [HS] ASC, [HID] ASC";
SqlCommand cmd = new SqlCommand
{
CommandText = comboBoxValue,
Connection = con
};
Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;
SqlDataAdapter da = new SqlDataAdapter(cmd);
dtAddress.Clear();
da.Fill(dtAddress);
dg_address.ItemsSource = dtAddress.DefaultView;
Mouse.OverrideCursor = System.Windows.Input.Cursors.Arrow;
}

编辑:Olivier Belanger和MindSwipe使工作解决方案成为可能。我还留下了有关如何使 LIKE 使用 % 参数的参考:在 SQL LIKE 子句中使用 SqlParameter 不起作用

public void InvokeDataGridAddress()
{
switch (ComboBoxSelection.Text)
{
case "NASLOV":
comboBoxValue = "SELECT * FROM [cbu_naslovi] WHERE [ADDRESS] LIKE @SearchText COLLATE Latin1_general_CI_AI";
break;
case "LASTNIK":
comboBoxValue = "SELECT [cbu_naslovi].* FROM [cbu_deli], [cbu_naslovi] WHERE [cbu_deli].LASTNIK LIKE @SearchText COLLATE Latin1_general_CI_AI AND [cbu_deli].IDX = [cbu_naslovi].ID";
break;
case "OBJEKT":
comboBoxValue = "SELECT * FROM [cbu_naslovi] WHERE [SO] LIKE @SearchText";
break;
case "PARCELA":
comboBoxValue = "SELECT * FROM [cbu_naslovi] WHERE [P1] LIKE @SearchText OR [P2] LIKE @SearchText OR [P3] LIKE @SearchText OR [P4] LIKE @SearchText OR [P5] LIKE @SearchText OR [P6] LIKE @SearchText OR [P7] LIKE @SearchText OR [P8] LIKE @SearchText OR [P9] LIKE @SearchText OR [P10] LIKE @SearchText OR [P11] LIKE @SearchText OR [P12] LIKE @SearchText OR [P13] LIKE @SearchText OR [P14] LIKE @SearchText OR [P15] LIKE @SearchText OR [P16] LIKE @SearchText OR [P17] LIKE @SearchText";
break;
}
comboBoxValue = comboBoxValue + " ORDER BY [ULICA] ASC, [OBMOCJE] ASC, LEN ([HS]) ASC, [HS] ASC, [HID] ASC";
SqlCommand cmd = new SqlCommand
{
CommandText = comboBoxValue,
Connection = con
};
cmd.Parameters.AddWithValue("@SearchText", '%' + search.Text + '%');
Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;
SqlDataAdapter da = new SqlDataAdapter(cmd);
dtAddress.Clear();
da.Fill(dtAddress);
dg_address.ItemsSource = dtAddress.DefaultView;
Mouse.OverrideCursor = System.Windows.Input.Cursors.Arrow;
}

简短的回答,是的,你总是需要担心SQL注入,你不会相信一些黑客对这些有多么有创造力。
虽然我在 C# 方面很有经验,但我从未在 C# 中使用过直接 SQL,但我总是将 EF 与 LINQ for Databases
一起使用,无论如何,这里是:

using (var con = new SqlClient.SqlConnection(conectionString))
using (var cmd = SqlClient.SqlCommand())
{
con.Open();
cmd.Connection = con;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT * FROM [cbu_naslovi] WHERE [ADDRESS] LIKE '%@Title%' COLLATE Latin1_general_CI_AI";
cmd.Parameters.Add("@Title", search.Text);
}

一些解释:使用
:使用关键字非常简单。基本上你放在括号之间的任何内容(例如Class c = new Class();(都需要实现 IDisposable,这个变量在大括号
Syntatic Candy之后被处理掉:通常一个using()需要跟上大括号 { },除非它是单个语句或另一个使用语句
Sql Stuff:con.Open打开我们与数据库的连接, 我们将其设置为我们的命令将与cmd.Connection = con一起使用的连接。
现在我们需要说它是什么类型的命令。通过执行cmd.CommandType = CommandType.Text我们告诉命令它是一个SQL查询。
现在我们需要实际定义我们的 Query,但不是将字符串与+连接起来,而是使用@SomeName作为占位符。
最后,我们将@SomeName替换为我们的实际值,方法是执行cmd.Parameters.Add("@SomeName", value)其中@SomeName可以是任何东西,但它需要与我们想要在SQL查询中替换的占位符相同。
这是我们实际上保护自己免受SQL注入攻击的地方,因为cmd.Parameters.Add()可以完成我们需要的所有事情,否则需要手动完成

。希望这有帮助,不要再让你感到困惑

注意:如果您对实体框架 (EF( 或 LINQ 感兴趣,这里有一个很好的来源:EF 数据库第一个教程

您容易受到 SQL 注入的攻击。

首先,最好像这样枚举您想要的选择内容:

SELECT Name, Address, City FROM [YourTable]而不是SELECT * FROM [YourTable]

其次,您应该在查询中插入参数,如下所示:

SELECT Name, Address, City FROM [YourTable] WHERE Name = @Name

在您的命令中:

cmd.Parameters.AddWithValue("@Name", YourValue)

希望对您有所帮助,

以下是一些链接: 防止SQL注入的好方法是什么? https://www.codeproject.com/Tips/706692/Preventing-SQL-Injection-Attacks

最新更新