防止动态代码中的sql注入

时间:2016-09-21 08:12:41

标签: c# sql-server sql-injection

我需要使用C#代码中的sql查询执行动态字符串,并阻止sql注入。

我的代码是这样的:

internal static string Get_Running_Cars(string from, string to)
        {
            return string.Format(
                 " declare @from as datetime = '{0}'" +
                 " declare @to as datetime = '{1}'" +
                 " select  top 3 DATEDIFF(second,starttime,endtime) as sum,carname as name" +
                 " from cars" +
                 " where @from < starttime and @to > endtime ", from, to
                 );
        }

在该代码中,我可以将恶意代码插入到这些字符串中。

我该如何安全使用它? 我应该阻止这些字符:';, -

3 个答案:

答案 0 :(得分:2)

正确,更简单,更快速的更安全的方法是使用参数化查询。假设您使用ADO.NET,您可以使用以下方法创建参数化查询:

function test_input($data) {
  $data = trim($data);
  $data = stripslashes($data);
  $data = htmlspecialchars($data);
  return $data;
}

您可以使用SqlCommand.ExecuteReader

执行该命令

使用Dapper,它更容易。一行将传递参数:

public SqlCommand BuildCarsCommand(DateTime from,DateTime to)
{
    var sql= "select  top 3 DATEDIFF(second,starttime,endtime) as sum,carname as name" +
         " from cars where @from < starttime and @to > endtime ";
    var cmd=new SqlCommand(sql);
    cmd.Paramerers.AddWithValue("@from",from);
    cmd.Parameters.AddWithValue("@to", to);

    return cmd;
}

这将在内部创建一个SqlCommand,传递参数,执行查询并将结果映射到汽车。

实体框架和大多数ORM也允许您运行参数化查询。

如果不是其中之一,您必须指定使用哪种数据访问方式。

在Entity Framework中,您可以使用LINQ来获取此查询,使用SqlFunctions.DateDiff计算日期差异:

 IEnumerable<Car> cars=connection.Query<Car>(sql,new {From=@from, To=@to});

答案 1 :(得分:1)

如果愿意,可以将其称为新手方法,但是如何预先尝试将输入解析为 internal static string Get_Running_Cars(string from, string to) { DateTime test1, test2; if (!DateTime.TryParse(from, out test1) || !DateTime.TryParse(to, out test2)) return null; //else is optional here, to show logic return string.Format( " declare @from as datetime = '{0}'" + " declare @to as datetime = '{1}'" + " select top 3 DATEDIFF(second,starttime,endtime) as sum,carname as name" + " from cars" + " where @from < starttime and @to > endtime ", from, to ); } 格式?

DateTime.TryParse()

heroku keys:add

答案 2 :(得分:1)

我使用EF,因此最好的答案是使用'SqlParameter'。

我构建了这个对象:

public class SqlQueryEntity
    {
        public string query { get; set; }
        public object[] _params { get; set; }
    } 

并使用DbRawSqlQuery发送它。

我需要插入带有'object'数组的查询,其中包含:

new SqlParameter[] { 
                    new SqlParameter("from", from),
                    new SqlParameter("to", to)
                }

'to'和'from'可以包含Datetime对象。