1

我的一位客户使用动态 SQL 作为存储过程的一部分。他们不想改变这一点。我正在构建应该使用有风险的存储过程的 MVC 网站。因此,在实体框架中使用参数并不能解决问题。

当我使用旧的和好的 SQL 助手时,我检查了 ExecuteQuery 函数中的所有参数并试图找到有风险的关键字。但是现在,当我使用本机 .NET Entity Framework 5 时,我没有共享功能,我可以在那里检查。

对每个特定领域都使用验证器对我不利。是否有一个选项可以为执行 SP 的实体框架部分制作过度添加功能或任何其他想法如何解决该问题?

4

1 回答 1

1

您没有说存储过程中的动态 SQL 是否使用参数。假设不是,最好的解决方案是在查询执行时为单引号编码字符串

例如创建一个方法string EncodeSqlString(string s) { return s.replace("'", "''"); }

然后调用这个方法

cmd.CommandText = "SP_FOO";
cmd.CommandType = CommandType.StoredProcedure;
EntityParameter param = new EntityParameter();
param.Value = EncodeSqlString(myString);
param.ParameterName = "MyParam";
cmd.Parameters.Add(param);

这将是最安全的方法,因为您只对传递给存储过程的字符串值进行编码,您没有在其他地方和不适合引号编码的上下文中使用这些值,并且您将降低截断的风险(只要在 SP 内没有发生截断)。这也只有在 SP 只使用这些值来构建 SQL 查询时才能正常工作——如果他们对它们做任何其他事情,那么这可能不是要走的路。

仅将字符串值传递给此方法。对于其他未加引号的类型,您应该在将它们传递给参数之前确保它们是正确的类型。例如对于一个int

  string number = Request.QueryString["Number"];
    if (int.TryParse(number, out myInt))
    {
      cmd.CommandText = "SP_BAR";
      cmd.CommandType = CommandType.StoredProcedure;
      EntityParameter param = new EntityParameter();
      param.Value = myInt;
      param.ParameterName = "MyParam";
      cmd.Parameters.Add(param);
    }
    else
    {
      // handle appropriately but do not use value
    }
于 2013-09-19T09:30:28.373 回答