我们有一个旧式C#应用程序,其中有许多针对用户传递的输入执行的内联SQL查询。因此,显然,SQL注入成为了问题。现在我们要修复它,但问题是我们要采用简约方法。没有太多代码。因此,对于我们来说,ORM和存储过程是不可行的。
我们必须更新每个内联语句以使用SQL参数化方法。但是,我正在寻找的是如果有一种通用的方法可以做到的。就像将查询发送到方法并动态生成SqlParameter
数组一样。
通过查询,我的意思是在不使用常规@
的情况下尽可能地执行查询。Select *
From table
Where id = 1 and name = 'Sean' and
location like '%cali'
像这样
List<Sqlparameters> params = new
List<Sqlparameters>()
var query = Select * from table where id = @v1 and name =@v2 and location like @v3
params.Add("v1", 1)
params.Add("v2", 'Sean')
params.Add("v3","%cali")
更新
现在,我有一种方法可以为我完成此任务。这将采用这样的sql文本
var sql = "select * from merchants where merchantID={" + Request["merchantid"] +"}"
方法
Public command Method(string query)
{
var cmd =new Command();
cmd.text="";
cmd.params=new List<SqlParameter>() ;
// code to trasform the query. Identify values based on the special char '{'. Dynamically adds placeholder variables and values into an array
cmd.text="select * from merchants where merchantID=@variable1
//Loops through variables and adds values
// to parameters
cmd.parameters.Add(new SqlParameter("variable1", value1);
return cmd;
}
答案 0 :(得分:2)
我写了一个快速的通用方法,可以执行您想要的操作。它使用正则表达式查找所有参数(必须以@字符作为前缀)
// This will build a SqlCommand from query text, and build SqlParameters
// foreach "@Param" in the query e.g. WHERE Name = @Name and Date = @Date
private SqlCommand GenerateSqlCommand(string queryText, params object[] paramValues)
{
// Build SqlCommand
var sqlCommand = new SqlCommand(queryText);
sqlCommand.CommandType = System.Data.CommandType.Text;
// Find all instances of @Param sql parameter names in the query
var matches = Regex.Matches(queryText, @"[@#]\w+");
for (int i = 0; i < matches.Count; i ++)
{
// Add this parameter to the command with the value from the paramValues
// Parameters passed into the method must be in order
// E.g. if the Query is "SELECT * FROM TABLE where Name = @Name and Date = @Date
// then paramValues must be { 'My Name', '04-24-2019' }
sqlCommand.Parameters.AddWithValue(matches[i].Value, paramValues[i]);
}
// Return command
return sqlCommand;
}
您可以使用params object []来传递查询中每个参数的值,从而构建SQL命令。用法示例为:
using (var conn = GetSqlConnection())
{
var param1 = "This is a parameter";
var param2 = "04/23/2019";
var param3 = 2;
using (var comm = GenerateSqlCommand("SELECT * FROM Users WHERE Username = @Username and Date = @Date and Id = @Id", param1, param2, param3))
{
comm.Connection = conn;
using (var reader = comm.ExecuteReader())
{
while (reader.Read())
{
// TODO: handle the results
reader.GetString(0);
reader.GetInt32(1);
}
}
}
}
答案 1 :(得分:0)
@Jon写的是一个很好的解决方案,但以防万一您想要更多。我建立了一个ORM库,可以处理几乎所有可能的senario。
现在您可以简单地像这样执行一个SQL。
var cmd = rep.GetSqlCommand("SELECT * FROM Users WHERE UserName = String[admin]");
String[..]
Date[..] and Guid[..]
稍后将转换为参数。
您也可以手动添加参数,请阅读文档以了解更多信息