1

I am making a web application for parameterized procedural world generation. Given the computational resources involved, this application involves a server backend for generating the world with an API connecting the server and client. This API is written in Python.

To expand the creative possibilities, I would like allow users to create plugins. The general method for doing this I see is providing a hook to the plugin makers, have them make a python module, then load the module and execute the hook from the module. The plugin functionality will apply only to the specific world where the plugin is loaded.

User-generated code opens you up to vulnerabilities. In client application settings, you can get hand-wavy by saying the risk falls on the end-user to ensure they trust the source. However, for server applications, when anyone could potentially contribute a plugin to a publicly available server, that is a huge risk to take.

What I would like is to restrict plugins to a functional methodology; the backend calls a function by passing some parameters I control, the function operates on that data, and returns a result of an expected format. I want to ensure the function has no access to state (global) variables, there is no IO (can't access files), and god forbid it can access the network.

So far, the only step in the right direction I see is to use import-safe, which declares functions/classes without executing module code. However, this does nothing to restrict the behavior of the imports themselves. It would be nice if there was a function wrapper in Python which limits scope, but I'm not aware of any.

What options are available to me?

Requirements:

  • Be implementable in Python/compatible frameworks
  • Use script language (preferably Python) that is general-purpose (and not application-specific)
  • Be uploaded by creator and stored on server (in a workshop of plugins)
  • Have safe way to provide hooks
  • Limit variables to local scope
  • Limit IO operations
  • Limit network operations
  • Allow internal imports (like Numpy) but with similar restrictions
2
  • There are two reasonable-ish ways to create a plugin security boundary: (1) in-process sandboxing on a stack that was deliberately created for this. Python was not created with sandboxing in mind. Good choices include JS, WebAssembly, or Lua, if you completely control the available capabilities. (2) Isolating the untrusted code in a separate process, letting the OS enforce sandboxing. This is fairly secure (depending on configuration), and is used by containerization tech like Docker. In Linux, a process can drop capabilities before it executes untrusted code, and can be given IO quotas.
    – amon
    Sep 18, 2023 at 7:52
  • However, typical SaaS offers extensibility either on the client side (offering a way to load user-defined extension into the web page), or via a REST API, perhaps using Webhooks to notify an extension of events. Those extensions will have to run on a separate server, though, typically provided by the extension developer. This would fail to satisfy your "workshop of plugins" requirement.
    – amon
    Sep 18, 2023 at 7:54

1 Answer 1

1

User-generated code opens you up to vulnerabilities. ... I want to ensure the function has no access to state (global) variables, there is no IO (can't access files), and god forbid it can access the network.

You're saying you want the benefits of container technology.

So fork off a child process that you chroot or jail, where numpy et al. are preinstalled and there's no net access. Or better, run it in a separate VM. It doesn't even need to be your infrastructure: replit or others could accept a request, run the user function, and return a JSON result.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.