从数据库返回一些值的安全方法(SQL SERVER &ASP.NET)

本文关键字:SERVER SQL ASP NET 方法 安全 返回 数据库 | 更新日期: 2023-09-27 18:16:01

下面的代码是否实现了从数据库检索数据的安全方式?请帮助我,我不了解SQL注入。有人告诉我这个代码很容易被注入。如果有,有人能解释一下吗?谢谢你。

public int CheckID(string column, string table, string wheres)
    {
        int i = 0;
        sqlcon = ConnectToMain();
        string sqlquery = "SELECT "+column+" FROM "+table+" "+wheres+"";
        using (sqlcon)
        {
            sqlcon.Open();
            SqlCommand sqlcom = new SqlCommand(sqlquery, sqlcon);
            using (sqlcom)
            {
                SqlDataReader dr = sqlcom.ExecuteReader();
                dr.Read();
                if (dr.HasRows)
                {
                    i = dr.GetInt32(0);
                }
                else
                {
                    i = 0;
                }
            }
            sqlcon.Close();
        }
        return i;
    }

从数据库返回一些值的安全方法(SQL SERVER &ASP.NET)

这段代码有太多的问题。

  • 表、列和标准以字符串形式传递并连接,这意味着代码容易被SQL注入。
  • 像表、列标准这样的数据库细节被溢出到函数的调用者中。您是否打算使用此方法查询访问者表以外的任何内容?
  • 当只需要一个值时使用读取器。
  • 连接在using块之外创建并存储在一个字段中。这绝对是内存泄漏,也可能是连接泄漏。只需在本地创建连接。

一个简单的命令调用修复了所有这些问题:

public int CheckIDVisitor(visitorName)
{
    string query = "SELECT ID FROM Visitors where Name=@name";
    using (var sqlConn=new SqlConnection(Properties.Default.MyDbConnectionString))
    using( var cmd=new SqlCommand(query,sqlConn))
    {
        var cmdParam=cmd.Parameters.Add("@name",SqlDbType.NVarChar,20);
        cmdParam.Value=visitorName;
        sqlConn.Open();
        var result=(int?)cmd.ExecuteScalar();
        return result??0;
    }
}

您也可以提前创建命令并将其存储在一个字段中。您可以在每次执行命令时将连接附加到该命令上:

public void InitVisitorCommand()
{
    string query = "SELECT ID FROM Visitors where Name=@name";
    var cmd=new SqlCommand(query,sqlConn);
    var cmdParam=cmd.Parameters.Add("@name",SqlDbType.NVarChar,20);
    _myVisitorCommand=cmd;
}
...
public int CheckIDVisitor(visitorName)
{
    using (var sqlConn=new SqlConnection(Properties.Default.MyDbConnectionString))
    {
        _myVisitorCommand.Parameters.["@name"]Value=visitorName;
        _myVisitorCommand.Connection=sqlConn;
        sqlConn.Open();
        var result=(int?)cmd.ExecuteScalar();
        return result??0;
    }
}
一个更好的选择是使用像Dapper这样的micro-ORM。Net删除所有这些代码:
public int CheckIDVisitor(visitorName)
{
    using (var sqlConn=new SqlConnection(Properties.Default.MyDbConnectionString))
    {
        string sql = "SELECT ID FROM Visitors WHERE name=@name"
        var result = conn.Query<int?>(sql, new { name = visitorName);
        return result??0;
    }
}

public int[] CheckIDVisitors(string []visitors)
{
    using (var sqlConn=new SqlConnection(Properties.Default.MyDbConnectionString))
    {
        string sql = "SELECT ID FROM Visitors WHERE name IN @names"
        var results = conn.Query<int?>(sql, new { names = visitors);
        return results.ToArray();
    }
}