2

我正在考虑通过在运行时从源代码编译来解析简单的数学方程。我听说在使用这种方法之前我应该​​注意一些安全注意事项,但我找不到任何关于此的信息。

谢谢

C# .net 2.0,winforms

4

4 回答 4

5

这种方法的问题是用户可以输入他们想要的任何代码(除非您对其进行清理)。他们可以输入代码来擦除您的所有文件。如果它在服务器上运行,请不 要这样做。此外,即使在台式机上,运行编译器来评估方程也非常慢。使用ANTLR之类的工具为您的方程制作语法,并将解析器嵌入到您的程序中。

于 2009-05-10T13:25:14.743 回答
4

前段时间我偶然发现了一个聪明的方法:利用 JScript 的eval函数。您可以创建一个简单的 JScript 类:

  class JsMath
  {
    static function Eval(MathExpression : String) : double
    {
      return eval(MathExpression);
    };
  }

像这样编译它:

jsc /目标:库 JsMath.js

现在您可以只引用 JsMath 库并使用 JsMath.Eval 方法。

于 2009-05-10T22:48:53.280 回答
2

编译是一种相对安全的操作。似乎只有在编译器中存在可利用的缓冲区溢出时才会成为问题。不过,运行生成的代码肯定存在安全风险。除非您仔细清理输入,否则您可能会在服务器应用程序中打开一个相当大的安全漏洞。

我很好奇你为什么采用这种方法。简单的数学方程具有相当严格的语法并且很容易解析。我确信有一些免费的库可用,如果不编写自己的库也不是一项艰巨的任务。这可能比使用编译器来验证数学表达式的语法要快得多。

于 2009-05-10T13:47:53.073 回答
2

如果 C#“方程式”可以保存并在用户之间交换,那么肯定存在安全风险。用户可以将恶意代码放入等式中,并让它在其他用户的机器上做坏事。或者用户可能会被简单地欺骗输入恶意“方程式”(想想这里的旧alt+F4 恶作剧)。

幸运的是,您可以在 .NET 沙箱中安全地托管不受信任的代码。一般的想法是您创建一个单独的 AppDomain(使用AppDomain.CreateDomain方法),它只有最小的权限,然后在那里加载和运行用户代码。

无论如何,将动态生成的程序集加载到单独的 AppDomain 中是一个好主意,因为它允许您再次卸载它们。

于 2009-05-11T00:29:16.797 回答