实现插件框架的最佳方法 - DLL 是唯一的方法(C/C++ 项目)吗?
简介:
我目前正在用 C/C++ 开发文档分类器软件,我将使用朴素贝叶斯模型进行分类。但我希望用户使用他们想要的任何算法(或者我将来想要的算法),因此我将架构中的算法部分作为一个插件分离出来,该插件将附加到主应用程序@应用程序启动。因此,任何用户都可以将自己的算法编写为插件,并将其与我的应用程序一起使用。
问题陈述:
我打算开发这个的方法是将用户想要使用的每个算法制作成一个DLL文件并放入特定的目录中。一开始,我的应用程序将搜索该目录中的所有 DLL 并加载它们。
我的问题:
(1) 如果将恶意代码制作为 DLL(并且具有插件框架规定的相同功能)并放入我的插件目录中会怎样?在这种情况下,我的应用程序会认为它是一个插件并选择它并调用它的函数,因此恶意代码可以轻松地关闭我的整个应用程序(在最坏的情况下可能使我的应用程序成为恶意代码启动器!!!) 。
(2) 使用DLL是实现插件设计模式的唯一方法吗? (不仅是因为担心恶意插件,而且是出于好奇而提出的一个普遍问题:))
(3)我认为很多软件都是用插件模型编写的以实现可扩展性,如果是这样,它们如何防御此类攻击?
(4) 总的来说,您对我使用插件模型来实现可扩展性的决定有何看法(您认为我应该考虑其他替代方案吗?)
谢谢
-MicroKernel :)
Introduction:
I am currently developing a document classifier software in C/C++ and I will be using Naive-Bayesian model for classification. But I wanted the users to use any algorithm that they want(or I want in the future), hence I went to separate the algorithm part in the architecture as a plugin that will be attached to the main app @ app start-up. Hence any user can write his own algorithm as a plugin and use it with my app.
Problem Statement:
The way I am intending to develop this is to have each of the algorithms that user wants to use to be made into a DLL file and put into a specific directory. And at the start, my app will search for all the DLLs in that directory and load them.
My Questions:
(1) What if a malicious code is made as a DLL (and that will have same functions mandated by plugin framework) and put into my plugins directory? In that case, my app will think that its a plugin and picks it and calls its functions, so the malicious code can easily bring down my entire app down (In the worst case could make my app as a malicious code launcher!!!).
(2) Is using DLLs the only way available to implement plugin design pattern? (Not only for the fear of malicious plugin, but its a generic question out of curiosity :) )
(3) I think a lot of softwares are written with plugin model for extendability, if so, how do they defend against such attacks?
(4) In general what do you think about my decision to use plugin model for extendability (do you think I should look at any other alternatives?)
Thank you
-MicroKernel :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
不用担心恶意插件。如果有人设法将恶意 DLL 潜入该文件夹,他们可能也有能力直接执行某些内容。
作为 DLL 的替代方案,您可以连接 Python 或 Lua 等脚本语言,并允许脚本插件。但也许在这种情况下您需要编译代码的速度?
有关嵌入Python,请参阅此处。这个过程并不是很困难。您可以静态链接到解释器,因此用户无需在其系统上安装 Python。但是,任何非内置模块都需要随您的应用程序一起提供。
但是,如果语言对你来说不太重要,嵌入 Lua 可能会更容易,因为它是专门为该任务设计的。请参阅其手册的本节。
参见 1。他们没有。
使用插件模型听起来像是一个很好的解决方案,前提是缺乏可扩展性确实是一个问题。如果事实证明确实有需求,那么对当前模型进行硬编码并稍后添加插件接口可能会更容易。添加很容易,但一旦人们开始使用它就很难删除。
Do not worry about malicious plugins. If somebody managed to sneak a malicious DLL into that folder, they probably also have the power to execute stuff directly.
As an alternative to DLLs, you could hook up a scripting language like Python or Lua, and allow scripted plugins. But maybe in this case you need the speed of compiled code?
For embedding Python, see here. The process is not very difficult. You can link statically to the interpreter, so users won't need to install Python on their system. However, any non-builtin modules will need to be shipped with your application.
However, if the language does not matter much to you, embedding Lua is probably easier because it was specifically designed for that task. See this section of its manual.
See 1. They don't.
Using a plugin model sounds like a fine solution, provided that a lack of extensibility really is a problem at this point. It might be easier to hard-code your current model, and add the plugin interface later, if it turns out that there is actually a demand for it. It is easy to add, but hard to remove once people started using it.
恶意代码并不是 DLL 的唯一问题。即使是善意的 DLL 也可能包含一个错误,该错误可能会导致整个应用程序崩溃或逐渐泄漏内存。
用高级语言加载模块会在一定程度上降低风险。例如,如果您想了解嵌入 Python,请查看文档。
另一种方法是在单独的进程中启动插件。它确实需要您付出更多的努力来实施,但它更安全。 Google 的 Chrome 网络浏览器使用单独的进程方法,并且他们有描述架构。
基本思想是为插件编写者提供一个库,其中包含与主应用程序通信的所有逻辑。这样,插件作者就有了他们使用的 API,就像他们编写 DLL 一样。维基百科有一个很好的进程间通信 (IPC) 方法列表。
Malicious code is not the only problem with DLLs. Even a well-meaning DLL might contain a bug that could crash your whole application or gradually leak memory.
Loading a module in a high-level language somewhat reduces the risk. If you want to learn about embedding Python for example, the documentation is here.
Another approach would be to launch the plugin in a separate process. It does require a bit more effort on your part to implement, but it's much safer. The seperate process approach is used by Google's Chrome web browser, and they have a document describing the architecture.
The basic idea is to provide a library for plugin writers that includes all the logic for communicating with the main app. That way, the plugin author has an API that they use, just as if they were writing a DLL. Wikipedia has a good list of ways for inter-process communication (IPC).
1) 如果您的插件文件夹中存在恶意 dll,则您可能已经受到威胁。
2)不,您可以从文件动态加载汇编代码,但这只是重新发明轮子,只需使用DLL即可。
3) Firefox 扩展不会,即使带有 javascript 插件也是如此。我所知道的其他所有内容都使用动态库中的本机代码,因此无法保证安全性。 Chrome 又拥有 NaCL,它会对二进制代码进行广泛的分析,如果不能 100% 确定它没有违反界限,就会拒绝它,尽管我确信随着时间的推移,它们会出现越来越多的漏洞。
4)插件没问题,只是限制给可信的人使用。或者,您可以使用 LUA、Python、Java 等安全语言,并将文件加载到该语言中,但仅限于不会损害您的程序或环境的 API 子集。
1) If there is a malicious dll in your plugin folder, you are probably already compromised.
2) No, you can load assembly code dynamically from a file, but this would just be reinventing the wheel, just use a DLL.
3) Firefox extensions don't, not even with its javascript plugins. Everything else I know uses native code from dynamic libraries, and is therefore impossible to guarantee safety. Then again Chrome has NaCL which does extensive analysis on the binary code and rejects it if it can't be 100% sure it doesn't violate bounds and what not, although I'm sure they will have more and more vulnerabilities as time passes.
4) Plugins are fine, just restrict them to trusted people. Alternatively, you could use a safe language like LUA, Python, Java, etc, and load a file into that language but restrict it only to a subset of API that wont harm your program or environment.
(1) 您能否使用操作系统安全设施来防止对搜索或加载 DLL 的文件夹进行未经授权的访问?这应该是你的第一个方法。
否则:运行威胁分析 - 风险是什么,已知的攻击媒介是什么,等等。
(2) 不一定。如果您想要编译的插件,这是最直接的 - 这主要是性能、对操作系统功能的访问等问题。如前所述,请考虑脚本语言。
(3)通常写为“防止恶意代码执行,限制对插件文件夹的访问”。
(4) 即使使用您还不熟悉的插件框架,也会产生相当多的额外成本。它增加了以下方面的成本:
仅当满足以下条件时才需要付费
(将代码移动到 DLL 中还有其他好处,但它们不属于插件本身)
(1) Can you use OS security facilities to prevent unauthorized access to the folder where the DLL's are searched or loaded from? That should be your first approach.
Otherwise: run a threat analysis - what's the risk, what are known attack vectors, etc.
(2) Not necessarily. It is the most straigtforward if you want compiled plugins - which is mostly a question of performance, access to OS funcitons, etc. As mentioned already, consider scripting languages.
(3) Usually by writing "to prevent malicous code execution, restrict access to the plugin folder".
(4) There's quite some additional cost - even when using a plugin framework you are not yet familiar with. it increases cost of:
That pays only if
(There are other benefits of moving code into DLL's, but they don't pertain to plugins as such)
一般来说,如果您不信任 dll,则无法以某种方式加载它。
即使它被解释,这对于几乎任何其他语言都是正确的。
Java 和某些语言很难限制用户可以执行的操作,而这仅因为它们在虚拟机中运行而有效。
所以不。加载 Dll 的插件只能来自可信来源。
您还可以在代码中嵌入一些解释器,例如 GIMP 允许编写插件
在Python中。
但请注意,由于任何解释语言的性质,这会慢得多。
Generally, if you do not trust dll, you can't load it one way or another.
This would be correct for almost any other language even if it is interpreted.
Java and some languages do very hard job to limit what user can do and this works only because they run in virtual machine.
So no. Dll loaded plug-ins can come from trusted source only.
You may also embed some interpreter in your code, for example GIMP allows writing plugins
in python.
But be aware of fact that this would be much slower because if nature of any interpreted language.
我们有一个非常相似的产品,它使用模块来扩展功能。
我们做了两件事:
我们使用 BPL 文件,这些文件在幕后是 DLL。这是 C++ Builder 中来自 Borland/Codegear/Embarcadero 的特定技术。我们利用一些 RTTI 类型功能来发布类似于 main (argv[]) 的简单 API,因此可以将任意数量的参数压入堆栈并由 DLL 弹出。
我们还将 PERL 嵌入到我们的应用程序中,以处理本质上更具业务逻辑的事物。
我们的软件是会计/ERP 套件。
We have a product very similar in that it uses modules to extend functionality.
We do two things:
We use BPL files which are DLLs under the covers. This is a specific technology from Borland/Codegear/Embarcadero within C++ Builder. We take advantage of some RTTI type features to publish a simple API similar to the main (argv[]) so any number of paramters can be pushed onto the stack and popped off by the DLL.
We also embed PERL into our application for things that are more business logic in nature.
Our software is an accounting/ERP suite.
查看现有的插件架构,看看是否有任何可以重用的东西。 http://git.dronelabs.com/ethos/about/ 是我来的一个链接谷歌搜索 glib + 插件时穿过。 glib 本身可能会更容易开发插件架构。 Gstreamer 使用 glib 并且有一个非常好的插件架构,可能会给你一些想法。
Have a look at existing plugin architectures and see if there is anything that you can reuse. http://git.dronelabs.com/ethos/about/ is one link I came across while googling glib + plugin. glib itself might may it easier to develop a plugin architecture. Gstreamer uses glib and has a very nice plugin architecture that may give you some ideas.