【发布时间】:2011-08-25 06:36:22
【问题描述】:
这就是提出这个问题的原因:www.devplusplus.com/Tests/CSharp/Hello_World。
虽然之前有人问过类似的问题,但网上的许多答案都有几个问题:
- 这必须是“.Net 4.0”风格,而不是传统模式。
- 程序集在内存中并且只会在内存中,它不能写入文件系统。
- 我想限制对文件系统、网络等的所有访问。
类似这样的:
var evidence = new Evidence();
evidence.AddHostEvidence(new Zone(SecurityZone.Internet));
var permissionSet = SecurityManager.GetStandardSandbox(evidence);
到目前为止,我找不到创建 AppDomain 和加载程序集的方法不在文件系统上,而是在 RAM 中。
同样,上面确定了其他解决方案不起作用的原因:1. 许多是针对 4.0 之前的版本,以及 2. 许多依赖于指向文件系统的“.Load”方法。
答案 2:我有一个程序集引用,因为它是由 CSharpCodeProvider 类生成的,所以如果您知道将 that 转换为字节数组的方法,那就完美了!
显示安全漏洞的示例代码
var provider = new CSharpCodeProvider(new Dictionary<String, String>
{ { "CompilerVersion", "v4.0" } });
var compilerparams = new CompilerParameters
{ GenerateExecutable = false, GenerateInMemory = true, };
var compilerResults = provider.CompileAssemblyFromSource(compilerparams,
string_Of_Code_From_A_User);
var instanceOfSomeClass = compilerResults.CompiledAssembly
.CreateInstance(className);
// The 'DoSomething' method can write to the file system and I don't like that!
instanceOfSomeClass.GetType().GetMethod("DoSomething")
.Invoke(instanceOfSomeClass, null);
那么为什么我不能先将程序集保存到文件中呢?
有两个原因:
- 此代码位于共享 Web 服务器上,对文件系统本身的权限有限。
- 此代码可能需要运行数千次,我不想要 1000 个 dll,即使是暂时的。
【问题讨论】:
-
就像你想用一个字节数组加载?或者您的意思是您正在使用 emit API 创建一个内存中的?
-
@tyranid 这是一个非常好的问题,我想我有点假设程序集是从可以转换为字节数组的东西加载的。如果它是动态发出的,发出程序集的代码可能需要在其他应用程序域中运行。
-
我以前曾解决过这个问题,但如果不将程序集写入磁盘,我找不到获取 COFF 字节 [] 的方法。如果您有访问问题,您也许可以使用隔离存储。或者,可能有一些方法可以设置写入内存的虚拟文件路径,但我不确定。
-
您不能将程序集保存到磁盘,然后以降低的权限将其加载到自己的 appdomain 中吗?将程序集保存到磁盘不会引入安全问题,将其加载回未选中会。
-
@Timothy,为什么不在临时位置创建程序集,然后在沙箱中执行它?您特别希望它在 RAM 中的原因是什么?
标签: c# security .net-4.0 appdomain