Safe Eval In Jinja

Jinja2
Safe expression evaluation
NeverUndefined
Error handling
Code execution
Python
The code showcases a secure expression evaluation function called `simple_eval` which utilizes Jinja2’s Environment and StrictUndefined. This ensures safer execution by preventing undefined variable errors. The NeverUndefined class offers personalized error messages for undefined variables.
Published

January 3, 2024


from jinja2 import Environment
from jinja2 import StrictUndefined
from jinja2.nativetypes import NativeEnvironment
def simple_eval(expr: str, globals_dict: dict = None):
globals_dict = globals_dict or {}
env = Environment(variable_start_string='${', variable_end_string='}', undefined=StrictUndefined)
template = env.from_string(expr).render(**dict(zip(globals_dict.keys(), globals_dict.keys())))
native_env = NativeEnvironment(undefined=StrictUndefined)
return native_env.from_string('{{' + template + '}}').render(**globals_dict)
if __name__ == '__main__':
print(simple_eval('${a}+1', {'a': 1}) == 2)
class NeverUndefined(jinja2.StrictUndefined):
def __init__(self, *args, **kwargs):
# ARGS: ("parameter 'myvar2' was not provided",)
# KWARGS: {'name': 'myvar2'}
if len(args) == 1:
info = args[0]
elif "name" in kwargs.keys():
info = f"Undefined variable '{kwargs['name']}"
else:
infoList = ["Not allowing any undefined variable."]
infoList.append(f"ARGS: {args}")
infoList.append(f"KWARGS: {kwargs}")
info = "\n".join(infoList)
raise Exception(info)