Question about ast.literal_eval

F

Frank Millman

Hi all

I am trying to emulate a SQL check constraint in Python. Quoting from
the PostgreSQL docs, "A check constraint is the most generic constraint
type. It allows you to specify that the value in a certain column must
satisfy a Boolean (truth-value) expression."

The problem is that I want to store the constraint as a string, and I
was hoping to use ast.literal_eval to evaluate it, but it does not work.
ValueError: malformed node or string: <_ast.Compare object at ...>

Is there a safe way to do what I want? I am using python 3.3.

Thanks

Frank Millman
 
M

matt.newville

Hi all



I am trying to emulate a SQL check constraint in Python. Quoting from

the PostgreSQL docs, "A check constraint is the most generic constraint

type. It allows you to specify that the value in a certain column must

satisfy a Boolean (truth-value) expression."



The problem is that I want to store the constraint as a string, and I

was hoping to use ast.literal_eval to evaluate it, but it does not work.




ValueError: malformed node or string: <_ast.Compare object at ...>



Is there a safe way to do what I want? I am using python 3.3.



Thanks



Frank Millman

You might find the asteval module (https://pypi.python.org/pypi/asteval) useful. It provides a relatively safe "eval", for example:
NotImplementedError
import os
'Import' not supportedNameError
__import__("os")
name '__import__' is not defined

This works by maintaining an internal namespace (a flat dictionary), and walking the AST generated for the expression. It supports most Python syntax,
including if, for, while, and try/except blocks, and function definitions, and with the notable exceptions of eval, exec, class, lambda, yield, and import. This requires Python2.6 and higher, and does work with Python3.3.

Of course, it is not guaranteed to be completely safe, but it does disallowimports, which seems like the biggest vulnerability concern listed here. Currently, there is no explicit protection against long-running calculations for denial of service attacks. If you're exposing an SQL database to user-generated code, that may be worth considering.

Cheers,

--Matt Newville
 
F

Frank Millman

You might find the asteval module (https://pypi.python.org/pypi/asteval) useful. It provides a relatively safe "eval", for example:

NotImplementedError
import os
'Import' not supported
NameError
__import__("os")
name '__import__' is not defined

This works by maintaining an internal namespace (a flat dictionary), and walking the AST generated for the expression. It supports most Python syntax,
including if, for, while, and try/except blocks, and function definitions, and with the notable exceptions of eval, exec, class, lambda, yield, and import. This requires Python2.6 and higher, and does work with Python3.3.

Of course, it is not guaranteed to be completely safe, but it does disallow imports, which seems like the biggest vulnerability concern listed here. Currently, there is no explicit protection against long-running calculations for denial of service attacks. If you're exposing an SQL database to user-generated code, that may be worth considering.

Thanks for this, Matt. I will definitely look into it.

Frank
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,814
Latest member
SpicetreeDigital

Latest Threads

Top