I have a Python project that dynamically loads Python scripts from a set of specified directories and executes an expected function off of them (the framework expects a function name that takes a certain number of parameters, but the implementation is unknown). To harden the security of this application, I would like to analyze the scripts to ensure that they are just pure math functions and, therefore, not interacting with any system components such as the HDD/SDD, the network, a database, etc. Is this even possible to do in Python?
I'm afraid this is not possible. After all, your problem boils down to asking "is this code malicious?", and it we could reliably answer this question then malware would no longer exist.
Another option would be to accept any code (with a reasonable size limit) and running it in a VM with no network access and that can only communicate with the host through an emulated serial port to get the data and return its result (you can provide helper functions in your environment like
set_output that would internally use the serial port to communicate with the host. You could make that even safer by running the VMs on physically separate machines that are considered untrusted and themselves only have a serial port to talk to the outside world. That way even if they do get exploited the attacker will have a hard time making any use of them.
Adding on from what André said, I think whitelisting would be your best bet.
If you'd like to come up with your own solution, you could either find, or build (given that python is whitespaced it wouldn't be too hard) a python parser using some regex magic and what not, to only allow certain code in a given script.
Possible: maybe. Feasible: seems unlikely. Simply restricting the imports will not secure the system. You'll need to parse the script and look for things like exec()
The biggest roadblock is that it's really hard to know that you've succeeded at blocking all dangerous operations.
If you can't trust the scripts, I think the safer way to go is to use a language specifically built for what you want to do or build your own. Trying to restrict the use of a general purpose language to what is known to be safe seems like a Sisyphean task. What you really want is a mathematical expression language, right?
Here's some code to give you an idea of what you are up against:
e = eval g = e("glo" + "bals") f = chr(101) f += chr(120) f += chr(101) f += chr(99) f += chr(102) f += chr(105) f += chr(108) f += chr(101) b = getattr(g()["__" + "builtins" + "__"], f) print b b("badstuff.py")
If you can't be bothered to run it, the print b displays:
<built-in function execfile>
This is just what I came up with in a few minutes. Clearly you need to restrict use of globals, eval, exec, execfile but I make no claim that this list is comprehensive.