我需要使用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
);
}
在该代码中,我可以将恶意代码插入到这些字符串中。
我该如何安全使用它?
我应该阻止这些字符:'
,;
,,
-
?
答案 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
);
}
格式?
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对象。