Juh*_*uha 5 python dictionary private class protected
如何保护我的变量免受此类攻击:
MyClass.__dict__ = {}
MyClass.__dict__.__setitem__('_MyClass__protectedVariable','...but it is not')
Run Code Online (Sandbox Code Playgroud)
上面改变了变量字典,之后是孩子们玩改变所有变量.上线对于此工作至关重要.如果您的字典__setitem__
被调整如下,则上述方法无效.
我想强制用户使用我的方法setProtectedVariable(value)
来更改变量,但我似乎没有办法在Python 2.7中这样做.有任何想法吗?
如果您从下面的代码中找到其他类似的漏洞,我也很感激(我注意到我还应该在我的inspect.stack
办理登机手续中添加文件名和行号myDict.__setitem__
).
这是我到目前为止所尝试的:
import inspect
class ProtectionTest:
__myPrivate = 0
def __init__(self):
md = myDict()
setattr(self,'__dict__', md)
def __setattr__(self, name, val):
if name == '__myPrivate':
print "failed setattr attempt: __myPrivate"
pass
elif name == '_ProtectionTest__myPrivate':
print "failed setattr attempt: _ProtectionTest__myPrivate"
pass
elif name == '__dict__':
print "failed setattr attempt: __dict__"
pass
else:
self.__dict__[name] = val
def getMyPrivate(self):
return self.__myPrivate
def setMyPrivate(self, myPrivate):
#self.__dict__['_ProtectionTest__stack'] = inspect.stack()[0][1:]
self.__dict__['_ProtectionTest__myPrivate'] = -myPrivate
class myDict(dict):
def __init__(self):
dict.__init__(self)
def __setitem__(self, key, value):
if inspect.stack()[1][3] == 'setMyPrivate':
dict.__setitem__(self,key,value)
else:
print "failed dict attempt"
pass
pt = ProtectionTest()
print "trying to change... (success: 1): "
pt.__myPrivate = 1
print pt.getMyPrivate(), '\n'
print "trying to change... (success: 2): "
pt._ProtectionTest__myPrivate = 2
print pt.getMyPrivate() , '\n'
print "trying to change... (success: 3): "
pt.__dict__['_ProtectionTest__myPrivate'] = 3
print pt.getMyPrivate() , '\n'
print "trying to change the function (success: 4): "
def setMyPrivate(self, myPrivate):
self.__dict__['_ProtectionTest__myPrivate'] = 4
pt.setMyPrivate = setMyPrivate
pt.setMyPrivate(0)
print pt.getMyPrivate(), '\n'
print "trying to change the dict (success: 5): "
pt.__dict__ = {}
pt.__dict__.__setitem__('_ProtectionTest__myPrivate',5)
print pt.getMyPrivate(), '\n'
print "Still working (correct output = -input = -100): "
pt.setMyPrivate(100)
print pt.getMyPrivate()
Run Code Online (Sandbox Code Playgroud)
sen*_*rle 18
我觉得有一些深刻的困惑激发了这个问题.私人变量不是为了阻止邪恶的"黑客".它们与安全无关.他们在那里推广良好的编程实践,如保持低耦合.
如果"邪恶的程序员"可以访问您的源代码,他或她可以做任何他或她想要的事情.调用变量"private"不会改变它.如果说邪恶的程序员试图破坏你在另一个系统上执行的程序......调用变量"私有"对你没有好处.它不会改变程序在内存中存储和操作的方式.它只是强制(以不必要的复杂方式IMO)分离关注点.
此外,值得注意的是,在正常情况下,您不必经历所有这些恶作剧......
MyClass.__dict__ = {}
MyClass.__dict__.__setitem__('_MyClass__protectedVariable','...but it is not')
Run Code Online (Sandbox Code Playgroud)
...分配给受保护的var.你甚至不必覆盖__dict__
.你可以这样做:
MyClass._MyClass__protectedVariable = '...but it is not'
Run Code Online (Sandbox Code Playgroud)
因为它真的不是.受保护,我的意思是.名称修改的主要目的是防止命名空间冲突.如果您只想要一个"私有"属性,只需在其前面加上一个下划线.期望您的用户尊重惯例,并期望您的滥用者无论您做什么都会打破它.
在Python中,您不能以这种方式"保护"属性.你为什么和你的来电者发生敌对关系?你和他需要就某些事情达成一致,这是其中之一.写出更好的文档,与他成为更好的朋友.我不知道你的真正问题是什么,但是用代码无法解决.
其他语言如Java和C++提供了分离private
等等,但Python根本没有.事后你不能把它搞砸.
如果你告诉我们更多关于这个邪恶的程序员是谁,以及为什么你和他不同意你的代码应该如何使用,我们可能会给你其他解决方案的想法.
AFAIK在Python中没有办法做到这一点.无论你做什么,任何人都可以随时复制你的源并删除你的黑客,或者(在大多数情况下)从类继承并覆盖它或直接重新分配方法.
但是:你为什么这么关心?如果你把它命名为__whatever
非常明确的文档,如果用户搞乱这个,那么发生的任何不好的事情都是他们自己该死的错误.