有没有办法阻止 C# 插件访问程序中的主 C# 应用程序?

发布于 2024-10-15 00:54:20 字数 536 浏览 2 评论 0原文

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

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

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

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

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

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

现在我们正在考虑第三方插件的可能性,显然,最初的设计具有与周围无人的开着的门上的“请勿进入”标志一样的安全性。

或者在万圣节时,一碗单独的九柱游戏上挂着“Take One”的牌子。

I have a program and a simple plugin architecture where the plugins implement a generic interface and the main program loads all plugins that implement this interface. It's the most common custom plugin architecture I have found so far, so that's what I'm using.

I am not using Microsoft's MEF and I have my reasons for not doing so. I'll leave it at that.

The issue is that when the plugins are loaded, no matter how 'blind' they are to the main program and it's forms/classes/etc. it can still access System.Windows.Forms.Application and can therefore gain access to my application and its currently running forms/methods/controls/etc.

I do not want this. Is there an way to restrict a plugin's access to the main Application?

EDIT: More info about the plugin

We (my boss and I) are currently discussing what the plugins need to do. They all obviously need to add functionality, but we originally decided to give each plugin access to the currently running form so that it can add controls and events directly to the form. This was based on the assumption that only we, the developers, would be writing them.

Now we are considering the possibility of third party plugins and the original design, obviously, has about as much security as a "Do Not Enter" sign on an open door with no one around.

Or a "Take One" sign hanging on a bowl of individual skittles on Halloween.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

回忆凄美了谁 2024-10-22 00:54:21

如果您可以在自己的AppDomains 中运行插件,那肯定会提高隔离级别。但与他们沟通也会变得很痛苦。如果不了解更多插件的用途,就很难知道这是否合适。

If you can run your plugins in their own AppDomains, that would certainly increase the level of isolation. It can also make it a pain to communicate with them though. Without knowing more about what the plugins are meant to do, it's hard to know whether or not that's appropriate.

一口甜 2024-10-22 00:54:21

因此,重申一下您最关心的问题:

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

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

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

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

除此之外,你确实无能为力。正如我所说,即使有上述保护措施,任何人都可以攻击您的应用程序。您最关心的应该是不要让用户感到惊讶。因此,建议适当注意您的应用程序运行的代码,但是一旦您的用户授予他们访问权限,这些扩展程序的作用并不是您真正可以完全控制的。

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

更新

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

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

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

So to restate your primary concern:

... and can therefore gain access to my application and its currently running forms/methods/controls/etc.

Before embarking on a complex and difficult means of loading, isolating, and restricting these extensions you should know a few things about Windows and the CLR. First, any program running on the box can use a number of Windows APIs to inject code into your process. Once code is loaded into your process, either by you or by the OS, accessing the CLR runtime and loading assemblies and/or running code in your existing AppDomain is fairly easy.

Knowing this you should weigh and balance the effort you excerpt to restrict 'extensions'. If I where building something like this I would be more concerned about other things than a malicious piece of extension code manipulating the state of my application. For example these are things you might consider:

  1. Only load extensions that are approved by your user, allow them to control what is allowed and allow them to revoke an extension later if desired. Look at Office or VStudio as an example.
  2. Ensure these approved extensions are untampered by using a code signing requirement (strong names, or code signing certificates).
  3. Consider having the ability to revoke an extension's ability to run remotely if it's found to be malicious.
  4. Prove a well-appointed Interface API to allow developers to easily implement desired behavior. If it's easy for them to use your interfaces to accomplish their task they won't need to 'hack'.

Beyond this there really isn't much else you can do. As I said, anyone can attack your application even with the above safe-guards. Your primary concern should be to not surprise your users. Thus the due-care in what code YOUR application runs is advisable, but what those extensions do once your users grant them access is not really something you can completely control.

This isn't to say that an AppDomain isolation won't provide you value, it may; however, IMHO getting the security restricted enough without limiting their ability to function will prove to be difficult.

UPDATE

... but if you load a plugin into an AppDomain which is configured with limited permissions how can it use this vector?

Correct, as I said in my closing statements, you can limit their access to unmanaged code within the AppDomain. This also limits their ability to develop a usable Windows experience. I expect that most WinForms applications use at least one PInvoke call or unmanaged COM control. This limitation imposed may be acceptable, I really can't say without more information about what functionality they are trying to provide.

All I was trying to say is that by installing and approving the extension your users are accepting the responsibility of allowing that extension to run. What that extension does and how malicious it may attempt to be is not your responsibility, assuming of course that you loaded the correct code. This is why I recommend focusing your energy on running approved code rather than worrying about what that code might do once it's in your process.

伴梦长久 2024-10-22 00:54:21

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

以下是适用于 WPF、Windows 窗体和经典的 Spy++(全部带有源代码)。

The best way to handle this is expose a documented plugin API. If your plugins run with full trust, then even if you run the plugin in its own AppDomain it can inject itself back into the application - then all it takes is someone to make a wrapper available and all the plugins are back to the same state they started in. If your API allows plugins to provide the desired features in a straightforward, consistent and documented manner, then that's what plugin developers will use.

The following are external UI hooks for WPF, Windows Forms, and the classic Spy++ (all with source).

赠意 2024-10-22 00:54:20

一种方法是将插件托管在它们自己的 AppDomain 中。您可以将这些 AppDomain 配置为具有有限的安全性,以防止它们访问主 AppDomain 中的资源。这确实使事情变得更加复杂,但会给你带来你想要的沙箱。

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

更新

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

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

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

更新 2

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

MAF - 托管插件Framework / System.Addin

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

One way of doing this is to host your plugins in their own AppDomains. You can configure these AppDomains to have limited security to prevent them from accessing resources in the main AppDomain. This does complicate things a lot, but will give you the sand-boxing you're after.

An additional benefit you receive from AppDomain hosting is that you can load and unload these domains if you wish to refresh plugins, plus you can protect your main AppDomain from crashes in your "child" domains.

Update

After seeing your update re. the capabilities of your plugin, AppDomains are not going to help if your plugin must have direct access to UI elements e.g. access to a form to add controls. You will not be able to give direct access to a form over an AppDomain boundary, or produce controls in one AppDomain and then marshal them across to another.

You could still consider hosting plugins in another AppDomain, but you will need to think about some sort of proxy mechanism so that actions like adding a control to a form can be done on behalf of a plugin, rather than letting the plugin access the form directly. For instance, you could pass in a form builder object which had methods such as AddButton. The proxy could then perform these actions of behalf of the plugin in the main domain. In this way you could provide a limited API for the plugin complete with required events.

This approach is by no means trivial, but once you have mastered the basics it's not too complicated.

Update 2

Things have moved on since rolling your own plugin frameworks with AppDomins back in the day. There is now support baked into the .Net framework since 3.5 for plugins:

MAF - Managed Addin Framework / System.Addin

It supports AppDomain isolation modes for plugins and has plugin loaders, etc. No need to roll your own.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文