# Remote Code Execution

A **remote code execution** (RCE) vulnerability allows an attacker to execute arbitrary code on you server. On a web-server, RCE vulnerabilities are typically cause when untrusted input from the HTTP request is evaluated as code.

## Remote Code Execution in Python

Python code can be evaluated dynamically using the global `eval(…)` and `exec(…)` functions. The former expects a string representing a (single) valid Python expression, while the later can execute multiple expressions – making it able to create new module, class, and function definitions. Both functions have access to the global and local state at the point of invocation.

Passing untrusted string as code to be evaluated allows an attacker to execute arbitrary code in your Python runtime – meaning they can steal sensitive information, read files from disk, or install malware. This is very dangerous!

To mitigate remote code execution attacks, you must ensure any strings are taken from a trusted source, or validated against an allow-list. To be totally secure, it’s often better to avoid `eval(…)` and `exec(…)` functions of Python altogether.

## Domain Specific Languages

Dynamic evaluation is often used to build *Domain Specific Languages* (DSLs) that allow expert users to write simple expressions that query data or encode business logic. If you find yourself writing a DSL in Python, consider using the `ast` (*Abstract Syntax Tree*) module, which allows you to parse expressions and evaluate each node atomically. This will help you “sandbox” the functions a user can invoke, removing the risks of arbitrary code execution.

Here’s a simple example of a DSL that can evaluate mathematical expressions:

“`python
import ast, operator, mathdef safe_eval(expression):
“””Evaluate a simple mathematical function by parsing an expression into an
abstract syntax tree and safely evaluating each node in turn.”””

def find_math_function(x, *args):
if x not in [x for x in dir(math) if not “__” in x]:
raise SyntaxError(f”Unknown function {x}()”)

return getattr(math, x)

binary_operations = {
ast.Add: operator.add,
ast.Sub: operator.sub,
ast.Mult: operator.mul,
ast.Div: operator.truediv,
ast.Mod: operator.mod,
ast.Pow: operator.pow,
ast.Call: find_math_function,
ast.BinOp: ast.BinOp,
}

unary_operations = {
ast.USub: operator.neg,
ast.UAdd: operator.pos,
ast.UnaryOp: ast.UnaryOp,
}

operations = tuple(binary_operations) + tuple(unary_operations)

syntax_tree = ast.parse(expression, mode=’eval’)

def _eval(node):
if isinstance(node, ast.Expression):
return _eval(node.body)
elif isinstance(node, ast.Str):
return node.s
elif isinstance(node, ast.Num):
return node.value
elif isinstance(node, ast.Constant):
return node.value
elif isinstance(node, ast.BinOp):
if isinstance(node.left, operations):
left = _eval(node.left)
else:
left = node.left.value
if isinstance(node.right, operations):
right = _eval(node.right)
else:
right = node.right.value
return binary_operations[type(node.op)](left, right)
elif isinstance(node, ast.UnaryOp):
if isinstance(node.operand, operations):
operand = _eval(node.operand)
else:
operand = node.operand.value
return unary_operations[type(node.op)](operand)
elif isinstance(node, ast.Call):
args = [_eval(x) for x in node.args]
function = find_math_function(node.func.id)
return function(*args)
else:
raise SyntaxError(f”Bad syntax, {type(node)}”)

return _eval(syntax_tree)

safe_eval(“1 + 1”) # Will return 2
safe_eval(“(100*10)+6”) # Will return 1006
safe_eval(“sqrt(16)+1”) # Will return 5.0
“`

## CWEs

* [CWE-94](https://cwe.mitre.org/data/definitions/94.html)

About ShiftLeft

ShiftLeft empowers developers and AppSec teams to dramatically reduce risk by quickly finding and fixing the vulnerabilities most likely to reach their applications and ignoring reported vulnerabilities that pose little risk. Industry-leading accuracy allows developers to focus on security fixes that matter and improve code velocity while enabling AppSec engineers to shift security left.

A unified code security platform, ShiftLeft CORE scans for attack context across custom code, APIs, OSS, containers, internal microservices, and first-party business logic by combining results of the company’s and Intelligent Software Composition Analysis (SCA). Using its unique graph database that combines code attributes and analyzes actual attack paths based on real application architecture, ShiftLeft then provides detailed guidance on risk remediation within existing development workflows and tooling. Teams that use ShiftLeft ship more secure code, faster. Backed by SYN Ventures, Bain Capital Ventures, Blackstone, Mayfield, Thomvest Ventures, and SineWave Ventures, ShiftLeft is based in Santa Clara, California. For information, visit: www.shiftleft.io.

Share

See for yourself – run a scan on your code right now