【问题标题】:Roslyn Scripting - Script without "System"Roslyn 脚本 - 没有“系统”的脚本
【发布时间】:2016-02-18 01:41:51
【问题描述】:

截至this 文章我想编写一个小 C# 脚本引擎来工作。我试过这段代码:

System.IO.StreamReader sr = new System.IO.StreamReader("example.txt");
var prog = sr.ReadToEnd();
sr.Close();
ScriptOptions so = ScriptOptions.Default;
Console.WriteLine(CSharpScript.RunAsync(prog, so).Result.GetVariable("sum").Value);
Console.ReadKey();

而example.txt的文件内容为:

System.IO.StreamReader sr = new System.IO.StreamReader("foo.txt");
string s = sr.ReadToEnd();
int sum = System.Convert.ToInt32(s);

现在我想限制用户只能使用 C# 的基本函数(使用 int、string、while、for)和一些自定义函数,而不是整个 .NET 库。但即使我不包括 System.IO als 引用,用户也可以键入 System.IO.something 并得到正确的结果。

是否有可能从脚本中删除对“系统”的访问权限

我很高兴有任何答案。

【问题讨论】:

  • 从脚本中删除对“系统”的访问权限”是什么意思?
  • 不应该有任何可能使用系统的任何元素。例如。编写脚本的用户根本不能使用 System.IO.StreamReader、System.Convert 或 System.Threading.Thread。
  • 你想实现沙盒,还是禁用System命名空间中的任何东西?后者可以通过分析您的输入代码并检查每个符号的名称空间来实现。前者可以通过将代码加载到单独的应用域中,并指定应用域的权限来完成。
  • 我想构建类似脚本 API 的东西,其中 C# 应用程序为用户提供了一些方法,例如包装文件访问。例如,我想确保文件只能写入某个文件夹及其子文件夹。因此,我想限制用户使用 System.IO 等,但使用我的预定义方法在他们执行请求之前检查。 AppDomain 方法对我来说似乎相当不错。但是我怎样才能在不限制它们的情况下提供这些方法呢?我可以从新的 AppDomain 回调原始应用程序以仅限制用户代码而不限制我的 API 方法吗?

标签: c# scripting visual-studio-2015 roslyn


【解决方案1】:

您需要正确设置ScriptingOptions,这意味着需要使用自定义MetadataReferenceResolver 而不是默认的@,这会自动解决丢失的引用。我不知道是否已经有一个仅根据其参数解析程序集的解析器,但您当然可以实现您的。查看TestMetadataReferenceResolver,它做了类似的事情。

更新 这不适用于 mscorlib 中定义的内容。

【讨论】:

  • 非常感谢您的帮助。我实现了自己的 ScriptOptions 和 RuntimeMetadataReferenceResolver 类(通过从原始类中删除 seal 关键字并从它们继承)并使 ResolveReference 方法返回一个空的 ImmutableArray。不幸的是,我的解决方案与原来的 ScriptOptions 完全一样。还有一点我必须改变的地方吗?
  • 您能提供我们检查它的代码吗?另外,我刚刚在ResolveMissingAssemblies 上看到了一条评论,说它只影响加载显式未被编译引用的程序集。值得检查一下这些程序集是什么。
  • 我检查了脚本对象,默认情况下它具有对 mscorlib 的引用。所以回到你原来的问题,你可能需要从代码中创建自己的编译并将其加载到它自己的 appdomain 中。查看这个(有点过时的)proof of concept 以对输入源代码进行沙盒处理。然后您可以指定IsolatedStorageFilePermission 以允许使用私有虚拟文件系统。
猜你喜欢
  • 2017-10-12
  • 2016-07-06
  • 1970-01-01
  • 1970-01-01
  • 2017-06-16
  • 2016-12-16
  • 2018-04-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多