C# 能否在另一个进程内的单独、安全、沙盒环境中执行?
Can C# be executed in a separate, safe, sandboxed environment inside another process?
在您希望允许用户定义搜索过滤器的情况下,是否可以获取一个字符串,对其进行动态编译,然后在沙箱中执行它,沙箱将不允许它访问沙箱。
假设我的应用有一个对象列表。我想允许高级用户在界面 中编写 C# (因此,实际上是在浏览器内的文本区域中)并将其作为字符串接收(作为 POST) .
像这样:
var foo = "bar";
return objects.Where(o => o.Property == foo);
同样,我会将其作为字符串获取(这不是从 Visual Studio 中编译出来的)。然后我可以将其动态编译成一个临时助手 class(这是简单的部分——我已经完成了)。
我没有做的是以我知道它不会对自身以外的资源产生负面影响的方式执行。因为,让我们面对现实吧,他们可以这样写:
File.Delete(Path.Combine(AppDomain.Current.BaseDirectory), "web.config"));
这显然很糟糕,但由于他们将 C# 编写为字符串并对其进行动态编译,我不确定我能做些什么。
我想做的是编译和执行这个字符串,使其只能访问我给它的资源。它将被编译成这样:
public static class Temp : IDynamicFilter
{
public static List<MyClass> Filter(List<MyClass> objects)
{
[their string goes here]
}
}
然后 Filter
将被调用(来自 IDynamicFilter
)。
我意识到这显然不是一个好主意。其中一些是假设性的——我对 运行 沙盒代码中代码的理论很感兴趣,超出了这个例子的细节。
.NET 就是为此而设计的。它完全支持沙盒,复杂的权限系统让您可以控制安全。基本思想是您 运行 单独的 AppDomain
中的 C# 代码,它根本没有任何权限。这可能会使与您的应用程序交互变得有些棘手 - 请注意这一点。
但是,代码未 运行 处于 完整 隔离状态。阻止 File.Delete
很容易。阻塞反射很容易(事实上,反射 仅 在完全可信的环境中是可能的,原因很明显 - 以及不安全的代码)。有可能用它以危险的方式与其他 AppDomain
交互——我真的不确定。选择一组确切的权限来为您提供您想要公开的功能,而不公开任何危险的东西可能也很棘手 - 您可能需要制作自己的沙箱方法,为您提供相当严格的方式来处理所需的工作(例如,这允许您通过您的方法允许某些文件操作,而不允许对沙盒应用程序进行 任何 文件操作)。
这对你来说足够安全吗?很难说。但是,用户是否有恶意使用它的动机?如果他们这样做,您可能想使用自己的语言,而不是使用 C#——一些非常具体的语言。如果他们不这样做,您实际上不必费心-即使处理代码权限也可能是一种矫枉过正( 难以使用-这可能会浪费时间)。
在您希望允许用户定义搜索过滤器的情况下,是否可以获取一个字符串,对其进行动态编译,然后在沙箱中执行它,沙箱将不允许它访问沙箱。
假设我的应用有一个对象列表。我想允许高级用户在界面 中编写 C# (因此,实际上是在浏览器内的文本区域中)并将其作为字符串接收(作为 POST) .
像这样:
var foo = "bar";
return objects.Where(o => o.Property == foo);
同样,我会将其作为字符串获取(这不是从 Visual Studio 中编译出来的)。然后我可以将其动态编译成一个临时助手 class(这是简单的部分——我已经完成了)。
我没有做的是以我知道它不会对自身以外的资源产生负面影响的方式执行。因为,让我们面对现实吧,他们可以这样写:
File.Delete(Path.Combine(AppDomain.Current.BaseDirectory), "web.config"));
这显然很糟糕,但由于他们将 C# 编写为字符串并对其进行动态编译,我不确定我能做些什么。
我想做的是编译和执行这个字符串,使其只能访问我给它的资源。它将被编译成这样:
public static class Temp : IDynamicFilter
{
public static List<MyClass> Filter(List<MyClass> objects)
{
[their string goes here]
}
}
然后 Filter
将被调用(来自 IDynamicFilter
)。
我意识到这显然不是一个好主意。其中一些是假设性的——我对 运行 沙盒代码中代码的理论很感兴趣,超出了这个例子的细节。
.NET 就是为此而设计的。它完全支持沙盒,复杂的权限系统让您可以控制安全。基本思想是您 运行 单独的 AppDomain
中的 C# 代码,它根本没有任何权限。这可能会使与您的应用程序交互变得有些棘手 - 请注意这一点。
但是,代码未 运行 处于 完整 隔离状态。阻止 File.Delete
很容易。阻塞反射很容易(事实上,反射 仅 在完全可信的环境中是可能的,原因很明显 - 以及不安全的代码)。有可能用它以危险的方式与其他 AppDomain
交互——我真的不确定。选择一组确切的权限来为您提供您想要公开的功能,而不公开任何危险的东西可能也很棘手 - 您可能需要制作自己的沙箱方法,为您提供相当严格的方式来处理所需的工作(例如,这允许您通过您的方法允许某些文件操作,而不允许对沙盒应用程序进行 任何 文件操作)。
这对你来说足够安全吗?很难说。但是,用户是否有恶意使用它的动机?如果他们这样做,您可能想使用自己的语言,而不是使用 C#——一些非常具体的语言。如果他们不这样做,您实际上不必费心-即使处理代码权限也可能是一种矫枉过正( 难以使用-这可能会浪费时间)。