Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I set the output of exec to variable python?

Tags:

python

I'm trying to set up a client and server in python so that the client sends some code, the server executes and processes it, and then sends the output back. I can execute the code received on the server with the command exec but whenever I try: var = exec "print 'word'", this doesn't work and fails with a syntax error; whereas when I run the same command not set to a variable, it works flawlessly. I am using python2.7

like image 928
Eli Smith Avatar asked Dec 20 '15 19:12

Eli Smith


1 Answers

Don't. Eval and Exec are very dangerous from untrusted inputs and there is no reasonable way to make them safe:

Using eval or exec from an untrusted input means you can get queries like this:

eval("os.system('clear')", {})

Use ast.literal_eval to evaluate safely evaluate a string to a Python object.

>>> import ast
>>> string = '{}'
>>> b = ast.literal_eval(string)
>>> b
{}
>>> type(b)
<class 'dict'>

If you can trust the input, use eval.

>>> string = '{}'
>>> b = eval(string)
>>> b
{}
>>> type(b)
<class 'dict'>

The Dangers of Eval and Exec

To explain why eval is dangerous, and why ast.literal_eval is safe, you have to understand how eval works: it merely takes a string and then interprets the input as Python code, allowing essentially anything to occur.

There are many ways to try to make eval and exec safe, however, all have various ways of getting around them. You can prevent nearly everything, including imports, builtins, etc., and someone can still find a way to get around it (see the link above).

ast.literal_eval gets around this by only allowing valid Python datatypes to be evaluated, such as dict, list, tuple, None, int, string, and float. This prevents the malicious execution of any code, but the application is much more limited. However, this extra security is well worth the loss of functionality for code coming from unknown sources.

A good example on how ast.literal_eval keeps you safe is the following snippet:

>>> import ast
>>> eval('__import__("os")')
<module 'os' from '/usr/lib/python3.4/os.py'>

>>> ast.literal_eval('__import__("os")')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.4/ast.py", line 84, in literal_eval
    return _convert(node_or_string)
  File "/usr/lib/python3.4/ast.py", line 83, in _convert
    raise ValueError('malformed node or string: ' + repr(node))
ValueError: malformed node or string: <_ast.Call object at 0x7f68e03db2e8>

Eval allows direct code execution, in this case, allowing access to the os module and therefore system tasks that could wipe your drive, while ast.literal_eval raises an error because it is not a recognized data type.

like image 76
Alexander Huszagh Avatar answered Sep 18 '22 01:09

Alexander Huszagh