WPF / SQL:用参数替换值?

时间:2018-10-23 12:40:31

标签: c# sql .net wpf

我是C#的新手,并且编写了以下代码。阅读完文档后,我意识到我的代码应该容易受到SQL注入的攻击,因为我没有在参数中使用参数(据我所知,您可以通过search.Text注入不需要的查询)。因为我本质上还是将自己的值锁定在“”引号内,所以我应该担心吗?

我在这里找到了一些指示,但是无法正常工作: How to use string variable in sql statement

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的参考:Use of SqlParameter in SQL LIKE clause not working

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;
}

2 个答案:

答案 0 :(得分:4)

简短的回答,是的,您始终需要担心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 '%@Text%' COLLATE Latin1_general_CI_AI";
    cmd.Parameters.Add("@Title", search.Text);
}

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

希望这会有所帮助,不会再使您感到困惑

注意:如果您对Entity Framework(EF)或LINQ感兴趣,这里是一个很好的来源:EF Database First tutorial

答案 1 :(得分:3)

您容易受到SQL注入的攻击。<​​/ p>

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

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

第二,您应该像这样在查询中插入参数:

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

在您的命令中:

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

希望有帮助,

以下是一些链接: What are good ways to prevent SQL injection? https://www.codeproject.com/Tips/706692/Preventing-SQL-Injection-Attacks