c# - 参数化查询与 SQL 注入(inject)

标签 c# asp.net

我是 Asp.net 的新手,刚开始使用类。我最近创建了一个类,它将为我处理大部分 SQL 查询,这样我就不必在我的所有文件上重复创建新连接。

我创建的方法之一将 SQL 查询作为参数并返回结果。我知道我应该使用参数化查询来避免 SQL 注入(inject)。我的问题是,当我将查询作为字符串参数传递时如何执行此操作?

例如,这是我将要调用的方法:

public static DataTable SqlDataTable(string sql)
{
    using (SqlConnection conn = new SqlConnection(DatabaseConnectionString))
    {
        SqlCommand cmd = new SqlCommand(sql, conn);
        cmd.Connection.Open();
        DataTable TempTable = new DataTable();
        TempTable.Load(cmd.ExecuteReader());
        return TempTable;
    }
}

所以从另一个文件我想像这样使用这个方法:

DataTable dt = new DataTable();

dt = SqlComm.SqlDataTable("SELECT * FROM Users WHERE UserName='" + login.Text  + "' and Password='" + password.Text + "'");

if (dt.Rows.Count > 0)
{
   // do something if the query returns rows
}

这可行,但仍然容易受到注入(inject)的影响,对吗?有没有办法可以将变量作为参数传递给字符串?我知道如果我为查询创建一个新的 SQLCommand 对象并使用 Parameters.AddWithValue 就可以做到这一点,但我希望我的所有 SQL 命令都在单独的类中。

最佳答案

This works but would still be vulnerable to injections right?

是的,您的代码非常容易受到 SQL 注入(inject)的攻击。<​​/p>

I know that I should be using parameterized queries to avoid SQL injections.

哦,绝对是。

My question is, how can I do this when I'm passing the query as a string parameter?

您根本不应该将查询作为字符串参数传递。相反,您应该将查询作为包含占位符和这些占位符的值的字符串参数传递:

public static DataTable SqlDataTable(string sql, IDictionary<string, object> values)
{
    using (SqlConnection conn = new SqlConnection(DatabaseConnectionString))
    using (SqlCommand cmd = conn.CreateCommand())
    {
        conn.Open();
        cmd.CommandText = sql;
        foreach (KeyValuePair<string, object> item in values)
        {
            cmd.Parameters.AddWithValue("@" + item.Key, item.Value);
        }

        DataTable table = new DataTable();
        using (var reader = cmd.ExecuteReader())
        {
            table.Load(reader);
            return table;
        }
    }
}

然后像这样使用你的函数:

DataTable dt = SqlComm.SqlDataTable(
    "SELECT * FROM Users WHERE UserName = @UserName AND Password = @Password",
    new Dictionary<string, object>
    {
        { "UserName", login.Text },
        { "Password", password.Text },
    }
);

if (dt.Rows.Count > 0)
{
   // do something if the query returns rows
}

关于c# - 参数化查询与 SQL 注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17509169/

相关文章:

c# - 如何在asp.net mvc4中发送电子邮件

javascript - 如何在 asp.net gridview 的代码隐藏中对 Eval 函数进行数据绑定(bind)

asp.net - ASP.NET 中 HTTP header 的争论控制

javascript - 按值匹配复选框

c# - 如何在 xamarin.android 中使用 HttpClient 将数据传递到服务器

c# - 如何使用 Dapper 从数据库中检索单个值

asp.net - 从数据库中获取 NULL 值并分配给 Date 变量

C# List<Object>.Equals 对象比较失败

c# - RSA 解密,仅使用 D、P、Q、U 参数 (GnuPG)

c# - 有生成图形轮廓的算法吗?