[New-bugs-announce] [issue36022] logging.config should not use eval()

STINNER Victor report at bugs.python.org
Mon Feb 18 06:29:28 EST 2019


New submission from STINNER Victor <vstinner at redhat.com>:

For logging "handlers", _install_handlers() of logging.config uses eval():

def _install_handlers(cp, formatters):
    """Install and return handlers"""
    hlist = cp["handlers"]["keys"]
    ...
    for hand in hlist:
        ...
        klass = section["class"]
        try:
            klass = eval(klass, vars(logging))
        except (AttributeError, NameError):
            klass = _resolve(klass)
        args = section.get("args", '()')
        args = eval(args, vars(logging))
        kwargs = section.get("kwargs", '{}')
        kwargs = eval(kwargs, vars(logging))
        h = klass(*args, **kwargs)
        ...
    ...
    return handlers

eval() is considered harmful regarding security: it executes arbitrary Python code.

Would it be possible to rewrite this function without eval?

I'm not sure of the format of the handler "class". Is it something like "module.submod.attr"? If yes, maybe a regex to validate the class would help? Maybe a loop using getattr() would be safer?

Maybe ast.literal_eval() would be enough? At least for args and kwargs?

$ python3
Python 3.7.2 (default, Jan 16 2019, 19:49:22) 
>>> import ast

# Legit positional and keyword arguments are accepted
>>> ast.literal_eval("(1, 2)")
(1, 2)
>>> ast.literal_eval("{'x': 1, 'y': 2}")
{'x': 1, 'y': 2}

# eval() executes arbitrary Python code
>>> eval('__import__("os").system("echo hello")')
hello
0

# literal_eval() doesn't execute system()
>>> ast.literal_eval('__import__("os").system("echo hello")')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.7/ast.py", line 91, in literal_eval
    return _convert(node_or_string)
  File "/usr/lib64/python3.7/ast.py", line 90, in _convert
    return _convert_signed_num(node)
  File "/usr/lib64/python3.7/ast.py", line 63, in _convert_signed_num
    return _convert_num(node)
  File "/usr/lib64/python3.7/ast.py", line 55, in _convert_num
    raise ValueError('malformed node or string: ' + repr(node))
ValueError: malformed node or string: <_ast.Call object at 0x7f60a400c780>

----------
messages: 335820
nosy: vinay.sajip, vstinner
priority: normal
severity: normal
status: open
title: logging.config should not use eval()
type: security
versions: Python 3.8

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue36022>
_______________________________________


More information about the New-bugs-announce mailing list