【问题标题】:How to make user-entered C# code safe?如何使用户输入的 C# 代码安全?
【发布时间】:2012-01-18 19:07:58
【问题描述】:

我正在构建一个条件格式功能,用户可以在其中输入类似的表达式

someFieldValue == "someValue"

我们会根据该表达式的结果应用格式。完成此任务的最快方法(使用功能齐全的表达式语法)似乎是使用CSharpCodeProvider.CompileAssemblyFromSource

因为表达式是用户输入的,这是一个巨大的安全漏洞(例如用户可以输入表达式someFieldValue == Process.Start("shutdown","/s /t 0"))。

问题: 如果这是针对生产系统的,如何确保输入的表达式不会导致问题?现在它只是一个内部工具,但如果我们将它暴露给生产系统,我想做好准备而不是走上一条路(C# CodeDom),只是为了以后废弃它。

一些会被认为不安全的事情:

  • 退出应用程序
  • 访问/修改文件/注册表/系统设置等本地资源
  • 修改内存中的对象
  • 调用进程崩溃
  • 启动应用程序
  • ...

由于列举所有你不能做的事情是不合理的,我的感觉是解决方案将涉及修改用户输入的表达式,以便它在暴露所有功能的代理对象上运行我们愿意公开表达。这意味着不允许在表达式中调用任意函数。这也意味着表达式不再是标准的 C# 代码,最终为此完全使用不同的语言语法可能更实用。

能够使用 C# 的好处是巨大,因为我们希望 C# 中的“插件”可以在表达式中使用,并且它允许与现有代码无缝集成。我接受一种解决方案是使用像 javascript 这样的脚本语言,但我想确保我们必须首先排除 C#。

【问题讨论】:

  • 也许使用 DynamicExpression 来允许一定数量的运算符/表达式。或者更一般地说,将表达式字符串解析为表达式树,其中有一个允许的节点列表。
  • 您正在描述一个用户攻击他们自己。允许用户攻击自己。为什么这是一个安全漏洞?
  • 网络服务器。表达式由客户端输入,但不受限制的访问可能会对服务器造成严重破坏。目前它只是供内部使用,所以这不是问题,但在生产中这是不可接受的。 AppDomain 解决了这个问题。
  • 有道理。当您提出安全问题时,您可能会考虑提及此类细节!

标签: c# security codedom


【解决方案1】:

我觉得你应该看看这个;

Assembly.CreateInstance and security

为此推荐的方法是在一个 沙盒应用程序域。给出了几个原因 http://blogs.msdn.com/b/shawnfa/archive/2006/04/19/579066.aspx 和一个 更重要的是,大多数其他潜在方法 自 .NET 4.0 起已弃用。

【讨论】:

  • 谢谢 - 我现在已经实现了这个,确实 AppDomains 正是我正在寻找的。对于那些有兴趣的人,一个很好的资源是this article
猜你喜欢
  • 1970-01-01
  • 2015-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-05
  • 2017-09-12
  • 2021-05-02
相关资源
最近更新 更多