C# 这个SELECT语句有什么不安全之处?

C# 这个SELECT语句有什么不安全之处?,c#,sql,asp.net,.net,C#,Sql,Asp.net,.net,我是ASP.NET和C的新手。从我正在读的一本书中,我写了一个SELECT语句,从数据库中获取一个值。然而,当我在网上搜索时,程序员说这是不安全的,不应该这样做。对于C语言的新手来说,我怎么知道我的编程方式是对是错?有规则吗?例如,编写此代码的正确方法是: using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["CustomerDataConnectionString"].Conn

我是ASP.NET和C的新手。从我正在读的一本书中,我写了一个SELECT语句,从数据库中获取一个值。然而,当我在网上搜索时,程序员说这是不安全的,不应该这样做。对于C语言的新手来说,我怎么知道我的编程方式是对是错?有规则吗?例如,编写此代码的正确方法是:

using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["CustomerDataConnectionString"].ConnectionString))
{
    SqlCommand cmd = new SqlCommand("SELECT CONVERT(varchar, CAST(plan_rate AS money), 1) FROM [dbo].[plans] WHERE plan_name = '" + Dropdownbox1.Text + "'", conn);
    conn.Open();

    using (conn)
    {
        Object result = cmd.ExecuteScalar();
        if (result != null)
            Label6.Text = "Plan rate: $" + result.ToString();
        else
            Label6.Text = "Plan is not available in this state.";

        conn.Close();
    }

    ....... rest of code

你是对的,这段代码是不安全的。考虑如果DROPUBBOXX1.文本包含恶意内容,如“将发生什么”;删除表dbo.plans-。结果查询将是

SELECT CONVERT(varchar, CAST(plan_rate AS money), 1)
FROM [dbo].[plans]
WHERE plan_name = '';

DROP TABLE dbo.plans --'
您的计划表将被删除

要防止出现这种情况,请使用参数化查询而不是字符串连接:

SqlCommand cmd = new SqlCommand("SELECT CONVERT(varchar, CAST(plan_rate AS money), 1) FROM [dbo].[plans] WHERE plan_name = @plan_name", conn);
cmd.Parameters.AddWithValue("@plan_name", Dropdownbox1.Text);
使用参数时,SQL查询引擎将参数值视为数据,而不是可能的命令。请在security.stackexchange.com上阅读此内容,以了解其中的区别

在一个无关的注释中,conn不需要有两个using语句;一个就够了:

using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["CustomerDataConnectionString"].ConnectionString))
{
    conn.Open();

    SqlCommand cmd = new SqlCommand("SELECT CONVERT(varchar, CAST(plan_rate AS money), 1) FROM [dbo].[plans] WHERE plan_name = @plan_name", conn);
    cmd.Parameters.AddWithValue("@plan_name", Dropdownbox1.Text);
    Object result = cmd.ExecuteScalar();

    if (result != null)
        Label6.Text = "Plan rate: $" + result.ToString();
    else
        Label6.Text = "Plan is not available in this state.";
}

你是对的,这段代码是不安全的。考虑如果DROPUBBOXX1.文本包含恶意内容,如“将发生什么”;删除表dbo.plans-。结果查询将是

SELECT CONVERT(varchar, CAST(plan_rate AS money), 1)
FROM [dbo].[plans]
WHERE plan_name = '';

DROP TABLE dbo.plans --'
您的计划表将被删除

要防止出现这种情况,请使用参数化查询而不是字符串连接:

SqlCommand cmd = new SqlCommand("SELECT CONVERT(varchar, CAST(plan_rate AS money), 1) FROM [dbo].[plans] WHERE plan_name = @plan_name", conn);
cmd.Parameters.AddWithValue("@plan_name", Dropdownbox1.Text);
使用参数时,SQL查询引擎将参数值视为数据,而不是可能的命令。请在security.stackexchange.com上阅读此内容,以了解其中的区别

在一个无关的注释中,conn不需要有两个using语句;一个就够了:

using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["CustomerDataConnectionString"].ConnectionString))
{
    conn.Open();

    SqlCommand cmd = new SqlCommand("SELECT CONVERT(varchar, CAST(plan_rate AS money), 1) FROM [dbo].[plans] WHERE plan_name = @plan_name", conn);
    cmd.Parameters.AddWithValue("@plan_name", Dropdownbox1.Text);
    Object result = cmd.ExecuteScalar();

    if (result != null)
        Label6.Text = "Plan rate: $" + result.ToString();
    else
        Label6.Text = "Plan is not available in this state.";
}

请告诉OP为什么它不安全。谢谢,先生,使用参数如何保护Select语句?我也可以这样做,如果我错了,请纠正我,现在我可以做的是:\'DROP TABLE dbo\u plans-'将存储在@plan\u名称中,并将传递给查询。如果这个问题是错误的,我很抱歉,非常感谢向您学习。@user3345212-参数不能简单地放在查询中。查询解析器实际上知道它们,并将整个字符串用作一个不可分割的字符串。你实际上得到了你期望的行为——它搜索plan_name等于的行;删除表dbo.plans-。整件事。它可能返回0行,但这也是预期的。@user3345212:这是一个很好的问题!Vilx是正确的,我也更新了我的答案。谢谢Vilx和Michael,很高兴你们仔细考虑了我的问题,没有比这个更好的答案了。非常感谢。请告诉OP为什么它不安全。谢谢您,先生,使用参数如何保护Select语句?我也可以这样做,如果我错了,请纠正我,现在我可以做的是:\'DROP TABLE dbo\u plans-'将存储在@plan\u名称中,并将传递给查询。如果这个问题是错误的,我很抱歉,非常感谢向您学习。@user3345212-参数不能简单地放在查询中。查询解析器实际上知道它们,并将整个字符串用作一个不可分割的字符串。你实际上得到了你期望的行为——它搜索plan_name等于的行;删除表dbo.plans-。整件事。它可能返回0行,但这也是预期的。@user3345212:这是一个很好的问题!Vilx是正确的,我也更新了我的答案。谢谢Vilx和Michael,很高兴你们仔细考虑了我的问题,没有比这个更好的答案了。非常感谢。