【发布时间】: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 解决了这个问题。
-
有道理。当您提出安全问题时,您可能会考虑提及此类细节!