【问题标题】:How to use a string to (safely) access deep Python properties?如何使用字符串(安全地)访问深层 Python 属性?
【发布时间】:2014-04-16 10:32:06
【问题描述】:

我正在尝试找到一种方法,允许我的用户请求 Python 对象的任意部分,并让服务器返回该数据,而不会意外允许他们请求他们不允许的内容拥有或做他们不被允许做的事情。

例如,假设服务器有这个数据:

my_stuff = {"alpha": ["bravo", "charlie", {"delta": "echo"}], "foxtrot": "golf"}

我想允许用户发送如下 HTTP 请求:

/path/to/my/script/?gimme=my_stuff[alpha][2][delta]

并让请求返回echo。同样,如果gimme=foxtrot,我想返回golf。

我不能把它传递给 eval() 对吗?单独的安全隐患将非常糟糕,但我无法想象性能也非常好。

请求的语法可以完全改变,要求是我允许用户请求服务器端对象的任意部分....但是只是对象,只读。

有没有一种安全/智能的方法可以做到这一点,还是我疯了?

【问题讨论】:

  • 你有一个嵌套的对象序列;将路径解析为字符串和整数列表,然后简单地解析该路径。使用字符串和整数访问项目是完全安全的,并且不可利用。

标签: python


【解决方案1】:

Martijn Pieters 让我走上了正确的道路,但仍有一些工作要弄清楚如何让 reduce() 遍历各种对象类型,所以我将在这里概述所有这些。

就我而言,my_stuff 实际上是一个具有许多不同属性类型的对象:

class Alpha(object):
    def __init__(self):
        bravo = [1, 2, 3]
        charlie = 7

class Delta(object):
    def __init__(self):
        echo = [Alpha(), Alpha()]
        foxtrot = {
            "golf": "hotel"
        }

所以像reduce(dict.__getitem__, path, my_stuff) 这样简单的东西在这里是行不通的。虽然以此为开始,但我最终得到了这个:

def get_parsed_attribute(self, result, field_name):
    try:
        return reduce(self.smart_getattr, field_name.split("__"), result)
    except (AttributeError, IndexError):
        return None  # We can assume that either the value is missing, or
                     # that key doesn't exist.  Either way, there's no harm.


@staticmethod
def smart_getattr(obj, key):
    if isinstance(obj, list):
        return list.__getitem__(obj, int(key))
    if isinstance(obj, dict):
        return dict.__getitem__(obj, key)
    return getattr(obj, key)

此代码确定我们正在处理的对象类型并执行适当的 getter,因此当 reduce() 调用它时,我们会得到与 Martijn 为我的简单字典建议的效果相同的效果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-23
    • 2011-06-22
    • 2021-11-03
    相关资源
    最近更新 更多