【问题标题】:How to use Linq instead of SQL Injection query for custom search如何使用 Linq 而不是 SQL 注入查询进行自定义搜索
【发布时间】:2014-05-30 05:18:25
【问题描述】:

我想使用 Linq 而不是下面的硬编码 Sql Injection 从 SqlServer DATABASE TABLES 中搜索。如何在C#Linq中检索动态生成的web控件输入文本并替换Linq中整个Sql注入进行搜索。

我的 C# 代码:

protected void Search_Button_Click(object sender, EventArgs e) 
{
    try 
     {  
       Table maintable = Select.FindControl("dynamic_filter_table_id") as Table;
       int rc = maintable.Rows.Count;
            if (rc == 1)
            {

                DropDownList D1 = maintable.FindControl("MainDDL") as DropDownList;
                if (D1.SelectedValue.Contains("decimal"))
                {
                    TextBox T1 = maintable.FindControl("txtbox1") as TextBox;
                    TextBox T2 = maintable.FindControl("txtbox2") as TextBox;
                    SqlDataAdapter sql = new SqlDataAdapter("SELECT F.Col1,F.Col2,V.COL1, col2,col3, col4 , col5, cl6 FROM TABLE1 as V , TABL2 as F WHERE V.Col1 = F.Col1 AND " + DDL1.SelectedItem.Text + " >= " + T1.Text + " AND " + DDl1.SelectedItem.Text + " <= " + T2.Text, con);

                    DataSet data = new DataSet();
                    sql.Fill(data);
                    con.Close();
                    Session["DataforSearch_DDL"] = data.Tables[0];
                }
            }
       }

    catch
    {
      ImproperSearch();
    }
}

【问题讨论】:

标签: c# asp.net linq search sql-injection


【解决方案1】:

为什么不直接重写查询以保证 SQL 注入安全? LINQ 不会给您带来任何好处。

您可以通过做两件事来实现这一目标。

首先是保护列名。这是通过指定列名允许使用哪些字符来实现的(比试图找出不允许使用的字符更安全)。在这种情况下,我删除了除字母和数字之外的所有内容。如果您有包含下划线的列名,只需将其添加到检查中即可。

接下来是使用参数化查询。每个 ADO.NET 驱动程序都内置了对此的支持,因此您只需使用 cmd.Parameters.AddWithValue 指定值。通过这样做,该值不是查询字符串的一部分,因此没有潜在的 SQL 注入。

using (var con = yourConnectionFactory.Create())
{
    using (var cmd = new SqlCommand(con))
    {
        var safeKey1 = OnlyLettersAndDigits(DDL1.SelectedItem.Text);
        var safeKey2 = OnlyLettersAndDigits(DDL2.SelectedItem.Text);

        cmd.CommandText = "SELECT F.Col1,F.Col2,V.COL1, col2,col3, col4 , col5, cl6 " + 
                              " FROM TABLE1 as V , TABL2 as F WHERE V.Col1 = F.Col1 " +
                              " AND " + safeKey1 + " >= @text1 " + 
                              " AND " + safeKey2 + " <= @text2 ";
            cmd.Parameters.AddWithValue("text1", T1.Text);
            cmd.Parameters.AddWithValue("text2", T2.Text); 
            var adapter = new SqlDataAdapter(cmd);

            var data = new DataSet();
            sql.Fill(data);
            Session["DataforSearch_DDL"] = data.Tables[0];
    }
}

public string OnlyLettersAndDigits(string value)
{
    var stripped = "";
    foreach (var ch in value)
    {
        if (char.IsLetterOrDigit(ch))
            stripped += ch;
    }

    return stripped;
}

【讨论】:

  • “LINQ 不会给你带来任何好处”不能再不同意了。从本质上讲,您不能使用 Linq 进行 SQL 注入(暴露代码中的错误),但是打开 SQL 注入漏洞只需要一个错误。 “为什么不”修复所有要参数化的查询的原因是,很难知道在 ADO.net 中哪里有可能进行 SQL 注入
  • @Aron: a) 您是否认真建议他将看起来像旧代码的代码转换为 EF 以实现 SQL 注入安全? b) 什么很难知道?切勿将用户输入的任何内容附加到查询字符串中。这是一个非常简单的规则。 c) 他的代码需要将字符串变量中的列名转换为 LINQ 表达式,这将比当前解决方案复杂得多。
  • 市场上有一些很好的微ORM,其中一些依赖于SQL的属性。鉴于属性构造函数参数必须是 const,#$%&ing 的范围要小得多。目前正在起草我的答案。我的观点是,如果每个程序员都遵循每条“简单”规则,那么世界上一半的错误将不存在。
  • @Aron:我知道 micro orms,我自己写过一个我故意避免使用 LINQ 的地方:blog.gauffin.org/2014/02/…。仍然。恕我直言,仅仅为了实现这么简单的事情而重写代码从来都不是一个好主意。
  • 您当然可以随意添加替代解决方案。我认为没有必要进一步讨论,因为我们似乎对这个主题有非常不同的看法:)
【解决方案2】:

您可以使用存储过程进行客户搜索,它适用于 ADO.Net 和 LINQ 方法。只需创建一个 SP 并将其添加到您的 DBML 文件中,非常简单。

这里是如何在 LINQ 中使用 SP 的链接

http://www.mssqltips.com/sqlservertip/1542/using-stored-procedures-with-linq-to-sql/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-19
    • 1970-01-01
    • 1970-01-01
    • 2014-10-14
    • 1970-01-01
    • 2014-08-29
    相关资源
    最近更新 更多