views:

88

answers:

4

I need to store source code for a basic function in a database and allow it to be modified through an admin interface. this code will take several numbers and strings as parameters, and return a number or None. I know that eval is evil, so I need to implement a safe way to execute a very basic subset of python, or something syntactically similar at least, from within a python based web-app.

The obvious answer, is to implement a DSL, however, I have no experience with that, nor do I have any idea where to begin, and a lot of the resources available seem to go a little over my head. I'm hoping that maybe there is something already out there which will allow me to essentially generate a secure python-callable function from a string in a database. the language really only needs to support assignment, basic math, if/else and case insensitive string comparisons. any other features are a bonus, but I think most things can be done with just that, no need for complex data structures, classes, functions etc.

If no such thing currently exists, i'm willing to look into the possibility of creating one, but as I said, I have no idea how to go about that, and any advice in that regard would be appreciated as well.

+1  A: 

Restricted Python environments are hard to make really safe.

Maybe something like lua is a better fit for you

gnibbler
Even Guido admits that restricting Python is hard http://neopythonic.blogspot.com/2009/03/capabilities-for-python.html
Cristian Ciupitu
A: 

You could implement a subset of Python by using the ast module to parse python code into an abstract syntax tree then walk the tree checking that it only uses the subset of Python that you allow. This will only work in Python 2.x, since Python 3 has removed the ast module.

However even using this method it will be hard to create something that is 100% secure, since even the most innocuous code could allow the user to write something that could blow up your application, e.g. by allocating more memory than you have available, or putting the program into an infinite loop using all the CPU.

Dave Kirby
This solution is also interesting and could work, my only problem with it is that is uses a default allow policy instead of a default deny, which something like pyparsing does.
Andre
+1  A: 

You could use Pyparsing to implement your DSL, provided the expressions involved won't be too complex (you don't give full details on that but you imply the requirements are pretty simple). See the examples page including specifically fourFn.py or simpleCalc.py.

Peter Hansen
This seems like the best suggestion, and simpleCalc supports *some* of what I need, however my DSL would also need to support case insensitive string comparisons and some sort of if/else blocks.
Andre
Along similar lines, something like http://waxeye.org may go a bit farther without getting you right into the Python AST stuff. See examples in the docs for it. You'd still have to write your own code to actually execute your mini-language, but it sounds restricted enough that it doesn't sound too hard to grow it from one of the calculator examples in either package, or some other like them.
Peter Hansen
+2  A: 

PySandbox might help. I haven't tested it, just found it linked elsewhere.

AKX