[Research] Plug-in management

Before I even started with Elixir I had an idea to create project like that, but with some experience now I have much more cleaner idea. I would like to ask community if some things are possible in Elixir and what API or libraries could help me with that.

Project targets:

  1. Any application/library could be also plug-in for my application, but it needs to add some code
  2. Any plug-in should not affect other plug-ins and main application
  3. My app should have a public allowed API that plug-in can use
  4. Any plug-in could ask for permission to add it’s own public API for other plug-ins
  5. Any plug-in should not directly work on database. Instead of it should:
    a) got (by main app API) an PostgreSQL schema that it will work on (to not conflict between models)
    b) ask for permission for each other schema to read data
    c) ask for permission for each other schema to write data

From targets what I need to is:

  1. Write a module that manages plug-ins:
    a) download from hex
    b) read mix.exs file and search for plugin_prepare alias
    c) run mix deps.get + tasks from plugin_prepare alias + mix test - check if all finishes without error - here I also need run migration with main application repo …
  2. Write permission API for:
    a) modules
    b) ask plug-in modules
    c) read and write to other schemas

First point not looks really hard, but second is much more harder:

  1. How I can run callback: &Module.function/args_count from another project (here: plug-in)
    I want to add plug-ins dynamically, so manually adding them to deps in mix.exs is not what I’m looking for.
  2. When running callback from point 1 how to add List of modules to that project? For example:
  defmodule HexName.Plugin.ModuleCallbackName do
    def callback_method_name do
      # firstly I need to add MainApp.PermissionManager here:
      allowed_apis = MainApp.PermissionManager.list
      # then add all modules from allowed_apis Map
      required_api = Match.fetch(allowed_apis, :api_id)
      unless required_api == :error do
        args = []
        apply(required_api, :function_name, args)
      end
    end
  end

Is it even possible to write something like I described in Elixir? Do you know any API/library that could help me with it? Do you know any article that will help me understand how could it work (apply callbacks between projects).
Maybe easier way is to implement something like WebSocket server-client for localhost connections (for communications between main project and plug-ins), but it requires that every project needs to have support for WebSocket …
Can you help me find a safest and easier way to implement it?

2 Likes

Well there are lots of ways to implement such a thing, but I guess it mostly depends on how sandboxed you want them to be, like if by public allowed API then behaviours or whatever are usual, if however by that you mean they should absolutely not be allowed to access anything else at all for security reasons, then use lua or some port program (or you can parse the elixir AST yourself and whitelist what you want, but that would be a pain, EVM languages are very good at introspecting a system)…

So yeah, first question, how sandboxed do you want it?

1 Like

@OvermindDL1: Thank you for your reply!
I would like to do it in Elixir way whenever it’s possible, so I would like to choose: they should absolutely not be allowed to access anything else, but I don’t want to end with something like: type_class :slight_smile:
Also parse the elixir AST yourself sounds like black magic for me. If I would decide to do it then I will do it only after some years, because I should increase my knowledge about Elixir and do it well.
So I’m looking for: easier method to safe communicate between two separate Elixir projects rather than parse the elixir AST myself - it’s why I think about using WebSocket (or similar) API for it. :slight_smile:

Yeah if you want to run code in the same VM then you are in for one of the levels of hell, I’d recommend not doing that. ^.^

If anything I’d say support lua, this sounds like exactly the use-case for it. Or opt for a websocket API if it can be done remotely and it is not time sensitive (all remote network communication will induce a noticable delay), etc…

1 Like

@OvermindDL1: WebSocket is only example - it’s technology that I already work with in Elixir language. I mean that main application will start each project as another system process in sandbox and they will be communicating by public API.
I don’t know if lua language is good choice, because I want that any Elixir project could be easily an plug-in for it for my app - so it need just to implement some callbacks like: AppName.Plugin.CallbackModeuleName.

‘System Process in a sandbox’, that sounds like a recipe to get hacked, to be honest… ^.^;

Just know, if there is direct EVM access, their code can do anything they want, so if that is fine… :slight_smile:

1 Like

@OvermindDL1: ah, I see - sorry I was focused on main app security rather than sysyem security
How about run each plug-in in something like chroot? I probably hear about something like it, but not remember it so much.

Chroot’s are not secure. VM’s are not secure. Illumos containers are ‘secure’ for some definition there-of, but better than the prior. Where would this plugins come from and who would be able to load them?

1 Like

@OvermindDL1: Only developer/service account and owner account, but keep in mind that owner do not need to know how it works inside.
Developer and owner will probably login only in local network - like 2 root accounts.
Developer account will be like owner account + some more info / options to help debug.

I don’t even hear about Illumos containers. Can you link to a good tutorial about it? Is it possible to have JSON API (like in Phoenix Channels) between main app and that plug-in in Illumos container?

@OvermindDL1:
I don’t found anything named "Illumos containers" directly. I see that Illumos is OS that derives from OpesnSolaris and therefore I found Solaris Containers and if I good understand then Illumos containers are better. I don’t feel bad with learn other distribution/OS, but keep in mind that Linux distributions are more popular in servers, so my solution will be good only for small percent of developers in production environment - it’s only why I will not try this, but I will keep in mind what you say and maybe I will personally try them myself in future. :smile:

I think again about this topic and found another way that looks not so bad for me.
If we want to be really secure (but without any virtual machine) then how about it:

  1. for each plug-in create an fake (can’t login) Linux account like: __project_name__plugins__plugin_name__ with plugins/plugin_name as home directory.
  2. each plug-in could work on tmp/plugin_socket (relative path) as normal Phoenix application with json API
    so if plug-in is a fake then it cannot do anything other that break itself and I’m not reserving all Linux TCP ports for (possibly) millions of plug-ins. :smiley:

For me this looks like a good balance between security and easy install. What do you think about it?

Search about Zones in particular SmartOS Zones.

about your idea : you are still really far from security but well. If you have to support Linux you can not be secure without VM in a nice way anyway.

1 Like

They call them “Zones”, basically they are the old BSD Jail model but extended through-out the kernel. It is fantastic for segmentation.

And there are way too many ways to break out of VM’s to the host OS if you search around online as well. VM’s are not built for security.

1 Like

@DianaOlympos and @OvermindDL1: by security you mean protect distribution/OS right?
I mean protect my project and basic protect for other things for example do not allow delete project files or format partition with my project and plug-ins - it’s why I started from my idea. Limited accounts should not affect whole project and other plug-ins. Anyway it looks really interesting and I already found some hosting services that offers this. Thank you!

As in protecting your server code from being subverted by the plugins. Protecting the host OS is also a noble goal, and quite necessary as well or the plugins could use those vectors to attack your server anyway.

I’m just having flashbacks of seeing PHP Forum plugins that completely take-over your web server, whether directly or by leaving an attack vector open that should not have been. ^.^;

1 Like