This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author vstinner
Recipients vinay.sajip, vstinner
Date 2019-02-18.11:29:28
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1550489368.54.0.864409036165.issue36022@roundup.psfhosted.org>
In-reply-to
Content
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>
History
Date User Action Args
2019-02-18 11:29:28vstinnersetrecipients: + vstinner, vinay.sajip
2019-02-18 11:29:28vstinnersetmessageid: <1550489368.54.0.864409036165.issue36022@roundup.psfhosted.org>
2019-02-18 11:29:28vstinnerlinkissue36022 messages
2019-02-18 11:29:28vstinnercreate