Dapper如何帮助防止SQL注入?我正在测试不同的DAL技术,必须选择一个来保护我们的网站。我倾向于Dapper(http://code.google.com/p/dapper-dot-net/),但需要一些帮助来学习安全性。
答案 0 :(得分:49)
Dapper如何帮助防止SQL注入?
这使得真的,真的易于完全参数化数据访问,而无需连接任何输入。特别是,因为您不需要跳过大量的“添加参数,设置参数类型,检查null ,因为ADO.NET具有糟糕的空值处理,冲洗/重复20个参数” ,通过使参数处理愚蠢方便。它还可以很容易地将行转换为对象,避免使用DataTable
的诱惑...每个人都获胜。
来自评论:
还有......那个小巧玲珑实际上有什么帮助呢?
要回答,让我们以marc_s的回复为例,并以旧方式编写,假设我们必须以connection
开头。那就是:
List<Dog> dogs = new List<Dog>();
using(var cmd = connection.CreateCommand()) {
cmd.CommandText = "select Age = @Age, Id = @Id";
cmd.Parameters.AddWithValue("Age", DBNull.Value);
cmd.Parameters.AddWithValue("Id", guid);
using(var reader = cmd.ExecuteReader()) {
while(reader.Read()) {
int age = reader.ReadInt32("Age");
int id = reader.ReadInt32("Id");
dogs.Add(new Dog { Age = age, Id = id });
}
while(reader.NextResult()) {}
}
}
除了我严重过度,因为它还涉及广泛的问题,如:
AddWithValue
很少存在)
dynamic
(对于多列)或基元等(对于单列)DataTable
答案 1 :(得分:35)
您只需要像往常一样使用参数化查询。由于Dapper只是“原始”SQL和ADO.NET的“微小”(并且非常薄)扩展 - 只需使用参数化的ADO.NET查询和提供参数。
请参阅Dapper-Dot-Net网站上的此示例:
var dog = connection.Query<Dog>("select Age = @Age, Id = @Id",
new { Age = (int?)null, Id = guid });
SQL查询使用参数 - 您将这些参数提供给“Dapper”查询。
总结一下:使用Dapper本身并不能帮助防止SQL注入本身 - 但是使用参数化 ADO.NET/SQL查询(并且这些查询完全由Dapper支持,没有问题)在所有)
答案 2 :(得分:-1)
是的,确保开发者的业务交易是每个开发人员的首要考虑。
为此,我总是更喜欢使用带有dapper的存储过程,并且我还使用包装方法来检查存储过程,以防止出现不必要的查询和单词:
private static bool IsStoredProcedureNameCorrect(string storedProcedureName)
{
if (string.IsNullOrEmpty(storedProcedureName))
{
return false;
}
if (storedProcedureName.StartsWith("[") && storedProcedureName.EndsWith("]"))
{
return Regex.IsMatch(storedProcedureName,
@"^[\[]{1}[A-Za-z0-9_]+[\]]{1}[\.]{1}[\[]{1}[A-Za-z0-9_]+[\]]{1}$");
}
return Regex.IsMatch(storedProcedureName, @"^[A-Za-z0-9]+[\.]{1}[A-Za-z0-9]+$");
}
还可以使用验证器将不需要的查询作为参数:
public static partial class Validator
{
private static readonly string[] Expressions = {
@"^.*((?i)select).*((?i)from).*$",
@"^.*((?i)insert into).*$",
@"^.*((?i)update).*((?i)set).*$",
@"^.*((?i)delete from).*$",
@"^.*((?i)create database).*$",
@"^.*((?i)create table).*$",
@"^.*((?i)create procedure).*$",
@"^.*((?i)create index).*$",
@"^.*((?i)alter database).*$",
@"^.*((?i)alter table).*$",
@"^.*((?i)alter procedure).*$",
@"^.*((?i)alter index).*$",
@"^.*\b((?i)exec(ute)?)\b.*$",
@"^.*((?i)shutdown with nowait).*$",
@"^.*((?i)waitfor delay).*$",
@"^.*((?i)drop table).*$"
};
public static bool DoesContainQuery(string input)
{
var inLowerCase = input.ToLower();
return Expressions.Any(expression => Regex.IsMatch(inLowerCase, expression));
}
public static string ReplaceSqlCharacter(string parameter)
{
parameter = parameter.Replace(";", "").Replace("[", "").Replace("]", "").Replace("--", "")
.Replace("_xp", "").Replace(@"/*", "").Replace(@"*/", "").Replace("@@", "");
return parameter;
}
}
您还可以看到我的详细信息,答案为here