我正在考虑通过在运行时从源代码编译来解析简单的数学方程式。我听说在使用这种方法之前我应该注意安全性因素,但我找不到任何相关信息。
由于
C#.net 2.0,winforms
答案 0 :(得分:5)
这种方法的问题是用户可以输入他们想要的任何代码(除非你清理它)。他们可以输入代码来删除所有文件。如果这是在服务器上运行,不执行此操作。此外,即使在桌面上,运行编译器只是为了评估方程式也非常慢。使用ANTLR之类的工具为方程式制作语法,并将解析器嵌入到程序中。
答案 1 :(得分:4)
前段时间我偶然发现了一个聪明的方法:利用JScript的 eval 功能。您可以创建一个简单的JScript类:
class JsMath
{
static function Eval(MathExpression : String) : double
{
return eval(MathExpression);
};
}
像这样编译:
jsc / target:library JsMath.js
现在您可以引用JsMath库并使用JsMath.Eval方法。
答案 2 :(得分:2)
编译是一种相对安全的操作。似乎只有在编译器中存在可利用的缓冲区溢出时才会出现问题。运行生成的代码肯定是一个安全风险。除非您小心清理输入,否则可能会在服务器应用程序中打开一个相当大的安全漏洞。
我很好奇为什么要采用这种方法。简单的数学方程具有相当严格的语法,并且非常容易解析。我确信有一些免费的图书馆,如果不写自己的图书馆并不是一项艰巨的任务。这可能比炮轰编译器以便验证数学表达式的语法要快得多。
答案 3 :(得分:2)
如果可以在用户之间保存和交换C#“方程式”,那么肯定存在安全风险。用户可以将恶意代码放入等式中,并使其在其他用户的计算机上执行不良操作。或者用户可能只是被欺骗进入恶意的“等式”(想想这里的旧alt+F4 prank)。
幸运的是,您可以在.NET沙箱中safely host untrusted code。一般的想法是,您创建一个单独的AppDomain(使用AppDomain.CreateDomain方法)只具有最小权限,然后在那里加载并运行用户代码。
无论如何,将动态生成的程序集加载到单独的AppDomain中是一个好主意,因为它允许您再次unload它们。