6

我有一个程序和一个简单的插件架构,其中插件实现了一个通用接口,主程序加载了所有实现这个接口的插件。这是迄今为止我发现的最常见的自定义插件架构,所以这就是我正在使用的。

我没有使用 Microsoft 的 MEF,我有理由不这样做。我就这样吧。

问题是,当插件被加载时,无论它们对主程序有多“盲目”,它是表单/类/等。它仍然可以访问System.Windows.Forms.Application,因此可以访问我的应用程序及其当前运行的表单/方法/控件/等。

我不想要这个。有没有办法限制插件对主应用程序的访问?

编辑:有关插件的更多信息

我们(我的老板和我)目前正在讨论插件需要做什么。它们显然都需要添加功能,但我们最初决定让每个插件访问当前正在运行的表单,以便它可以直接向表单添加控件和事件。这是基于这样的假设,即只有我们开发人员会编写它们。

现在我们正在考虑第三方插件的可能性,显然,原始设计的安全性与一扇敞开的门上的“请勿进入”标志一样多,周围没有人。

或者在万圣节挂在一碗个人吃喝玩乐上的“Take One”标志。

4

4 回答 4

4

一种方法是将插件托管在它们自己的 AppDomain 中。您可以将这些 AppDomain 配置为具有有限的安全性,以防止它们访问主 AppDomain 中的资源。这确实使事情复杂化了很多,但会给你你所追求的沙盒。

您从 AppDomain 托管获得的另一个好处是,如果您希望刷新插件,您可以加载和卸载这些域,此外,您可以保护您的主 AppDomain 免受“子”域中的崩溃。

更新

看到你的更新后重新。如果您的插件必须能够直接访问 UI 元素,例如访问表单以添加控件,那么您的插件的功能,AppDomains 将无济于事。您将无法通过 AppDomain 边界直接访问表单,或在一个 AppDomain 中生成控件,然后将它们编组到另一个。

您仍然可以考虑在另一个 AppDomain 中托管插件,但您需要考虑某种代理机制,以便可以代表插件完成向表单添加控件等操作,而不是让插件直接访问表单. 例如,您可以传入一个表单构建器对象,该对象具有诸如AddButton. 然后代理可以代表主域中的插件执行这些操作。通过这种方式,您可以为包含所需事件的插件提供有限的 API。

这种方法绝不是微不足道的,但是一旦您掌握了基础知识,它就不会太复杂。

更新 2

自从使用 AppDomins 推出您自己的插件框架以来,事情已经发生了变化。从 3.5 开始,.Net 框架现在支持插件:

MAF - 托管插件框架 / System.Addin

它支持插件的 AppDomain 隔离模式,并具有插件加载器等。无需自己滚动。

于 2011-01-26T20:04:03.690 回答
4

如果您可以自己运行插件AppDomains,那肯定会提高隔离级别。但是,与他们交流也会很痛苦。在不了解插件的用途的情况下,很难知道这是否合适。

于 2011-01-26T20:02:10.090 回答
1

因此,重申您的主要关注点:

...因此可以访问我的应用程序及其当前运行的表单/方法/控件/等。

在开始使用复杂而困难的方法来加载、隔离和限制这些扩展之前,您应该了解一些关于 Windows 和 CLR 的知识。首先,在盒子上运行的任何程序都可以使用许多 Windows API 将代码注入您的进程。一旦代码被您或操作系统加载到您的进程中,访问 CLR 运行时并加载程序集和/或在现有 AppDomain 中运行代码是相当容易的。

知道这一点,您应该权衡和平衡您摘录以限制“扩展”的努力。如果我在哪里构建这样的东西,我会更关心其他事情,而不是操纵我的应用程序状态的恶意扩展代码。例如,这些是您可能会考虑的事情:

  1. 仅加载用户批准的扩展,允许他们控制允许的内容,并允许他们稍后在需要时撤销扩展。以 Office 或 VStudio 为例。
  2. 使用代码签名要求(强名称或代码签名证书)确保这些已批准的扩展未被篡改。
  3. 如果发现扩展程序是恶意的,请考虑撤销扩展程序远程运行的能力。
  4. 证明一个设备齐全的接口 API 以允许开发人员轻松实现所需的行为。如果他们很容易使用您的界面来完成他们的任务,他们就不需要“破解”。

除此之外,您真的无能为力。正如我所说,即使有上述安全措施,任何人都可以攻击您的应用程序。您主要关心的应该是不要让您的用户感到惊讶。因此,应谨慎对待您的应用程序运行的代码,但是一旦您的用户授予他们访问权限,这些扩展程序会做什么并不是您可以完全控制的事情。

这并不是说 AppDomain 隔离不会为您提供价值,它可能会;然而,恕我直言,在不限制其功能的情况下获得足够的安全限制将被证明是困难的。

更新

...但是如果您将插件加载到配置有有限权限的 AppDomain 中,它如何使用此向量?

正确,正如我在结束语中所说,您可以限制他们访问 AppDomain 中的非托管代码。这也限制了他们开发可用 Windows 体验的能力。我希望大多数 WinForms 应用程序至少使用一个 PInvoke 调用或非托管 COM 控件。施加的这种限制可能是可以接受的,如果没有更多关于他们试图提供的功能的信息,我真的不能说。

我想说的是,通过安装和批准扩展,您的用户将承担允许该扩展运行的责任。该扩展程序的作用以及它可能尝试的恶意程度不是您的责任,当然前提是您加载了正确的代码。这就是为什么我建议您将精力集中在运行已批准的代码上,而不是担心该代码在您的流程中可能会做什么。

于 2011-01-26T21:03:00.830 回答
0

处理这个问题的最好方法是公开一个文档化的插件 API。如果您的插件以完全信任的方式运行,那么即使您在其自己的 AppDomain 中运行该插件,它也可以将自己注入回应用程序中 - 然后只需有人提供一个可用的包装器,所有插件都将恢复到与它们相同的状态如果您的 API 允许插件以直接、一致和记录的方式提供所需的功能,那么这就是插件开发人员将使用的。

以下是 WPF、Windows 窗体和经典 Spy++(均带有源代码)的外部 UI 挂钩。

于 2011-01-26T20:47:54.620 回答