views:

132

answers:

7

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 :)

+5  A: 
  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.

  2. 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.

  3. See 1. They don't.

  4. 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.

Thomas
@Thomas Thank you for the answer :) Can you please provide some pointer for me to start with integrating scripting languages with my app. (If I integrate say Python with my app, then wouldn't that make Python VM as a dependency for my app? In most Windows PCs, users will not have Python!!!) Or are there any generic interpreters that I can configure for my purpose and compile with my app?
Microkernel
Python as an extension language is awesome, but if you're concerned about having large external dependencies, check out Lua. It's built specifically as an extension language, you can have it running in your app in an hour, and it is small and self contained.
Matt Curtis
@Microkernel: Edited my answer with some additional pointers.
Thomas
+1  A: 

What if a malicious code is made as a DLL

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.

Is using DLLs the only way available to implement plugin design pattern?

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.

Artyom
+3  A: 

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.

Longpoke
On 2) the OS may mark the program data as non-execute, preventing you from loading arbitrary code into your program space. I second the motion to just use a DLL.
Mark Ransom
Well, you can use VirtualProtect to mark code in a heap as executable, which is what most people do to avoid problems with DEP or NX. But yes, a DLL is fine.
Longpoke
+2  A: 

(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:

  • the core application (plugin functionality)
  • the plugins (much higher isolation)
  • installation
  • debugging + diagnostics (bugs that occur only with a certain combinaiton of plugins)
  • administration (users must know of, and manage plugins)

That pays only if

  • installing/updating the main software is much more complex than updating the plugins
  • individual components need to be updated individually (e.g. a user may combine different versions of plugins)
  • other people develop plugins for your main application

(There are other benefits of moving code into DLL's, but they don't pertain to plugins as such)

peterchen
@peterchen Thank you for the answer :) Can you please provide some pointer for me to start with the integrating scripting languages with my app. (If I integrate say Python with my app, then wouldn't that make Python VM as a dependency for my app? In most Windows PCs, users will not have Python!!!). Or are there any generic interpreters that I can configure and compile with my app?
Microkernel
Set Matt Curtis' comment on Thomas' reply. I'd say the same :)
peterchen
+3  A: 

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).

Daniel Stutzbach
@Daniel Stutzbach, "launch the plugin in a separate process", looks gr8 idea. Thanks for mentioning.
Microkernel
A: 

We have a product very similar in that it uses modules to extend functionality.

We do two things:

  1. 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.

  2. We also embed PERL into our application for things that are more business logic in nature.

Our software is an accounting/ERP suite.

Eric M
A: 

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.

Sid H