setattr
和getattr
类似于我的编程风格(主要是科学的东西,我对python的了解是自我告诉)。
考虑到exec
和eval
继承了潜在的危险,因为在某些情况下它们可能导致安全问题,我想知道setattr
是否认为相同的参数是有效的。 (关于getattr
我发现this question包含了一些信息 - 尽管论证并不十分令人信服。)
据我所知,setattr
可以使用而不用担心太多,但说实话我不相信我的python知识足以确定,如果我错了我想试试并摆脱使用setattr
的习惯。
非常感谢任何输入!
答案 0 :(得分:10)
首先,它绝对可以使现有的安全漏洞更容易。
例如,假设你有代码执行exec
,eval
,SQL查询或通过字符串格式化构建的URL等等。让我们说你正在传递,比如{{1} }或过滤的locals()
到格式化命令或__dict__
上下文或其他任何内容。使用eval
可以明显加宽安全漏洞,使我更容易找到攻击代码的方法,因为您无法再确定将要传递给这些函数的内容。
但是,如果你不做任何其他不安全的事情怎么办? setattr
安全吗?
没有那么糟糕,但它仍然不安全。如果我可以影响您正在设置的属性的名称,我可以,例如,替换您想要的任何方法。
您可以尝试通过例如首先检查旧值是否不可调用,或者不是方法类型描述符等来防止这种情况。以同样的方式,您可以尝试防止人们在setattr
中调用函数或在SQL参数中添加引号和分号等等。这实际上与任何其他情况相同。尝试关闭所有通往开门的非法路径要困难得多,而不是一开始就不打开门。
如果名称永远不会来自可能受用户影响的任何内容,该怎么办?
那么,在这种情况下,你为什么要使用eval
?没有充分理由使用文字调用setattr
。
无论如何,当Lattyware表示通常有更好的方法来解决手头的问题时,他几乎肯定会谈论可读性,可维护性和惯用性。但使用这些更好的方法的副作用是你也经常避免任何安全隐患。
90%的时间,解决方案是使用setattr
而不是对象。与Javascript不同,它们在Python中并不相同,并且它们并不意味着以相同的方式使用。 dict
没有方法,继承或内置特殊名称,因此您不必担心任何问题。它还有一个更方便的语法,您可以说dict
而不是d['foo']
。它可能更有效率。等等。但最终,使用setattr(o, 'foo')
的原因是概念性原因:dict
是一个命名的值集合;类实例是模型空间对象的表示,并且它们不是同一个东西。
那么,为什么dict
甚至存在?
出于与其他低级功能相同的基本原因,例如能够访问setattr
或im_func
,或拥有func_closure
和traceback
等模块,或者像其他任何方法一样处理特殊方法,或者imp
和exec
。
首先,您可以使用这些低级工具构建更高级别的东西。例如,要构建eval
,您需要collections.namedtuple
或exec
。
其次,您偶尔需要在运行时对代码进行修补,因为您无法在编译时修改它(或者甚至可能看到它),而像setattr
这样的工具对于这样做是必不可少的。
setattr
功能 - 与setattr
非常相似 - 经常被来自Javascript,Tcl或其他一些语言的人滥用。但只要它可以用得很好,你就不想把它从语言中拿出来。 (TOOWTDI不应该这样理解,只能编写一个程序。)
但这并不意味着你应该尽可能地使用这些东西。您不会写eval
而不是mylist.__getitem__(slice(1, 10, 2))
。有时,能够直接调用mylist[1:10:2]
或明确构建__getitem__
对象是一个基础,可以让其余的代码更加pythonic,或者本地化一个变通方法以避免感染其余的码。否则,有更清晰,更简单的方法。