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