如何保护python类变量免受邪恶程序员的侵害?
Posted
技术标签:
【中文标题】如何保护python类变量免受邪恶程序员的侵害?【英文标题】:How to protect python class variables from an evil programmer? 【发布时间】:2012-02-29 01:20:55 【问题描述】:如何保护我的变量免受此类攻击:
MyClass.__dict__ =
MyClass.__dict__.__setitem__('_MyClass__protectedVariable','...but it is not')
以上内容更改了变量字典,之后更改所有变量是孩子们的游戏。上线对于这项工作至关重要。如果您的字典的__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()
【问题讨论】:
您为什么要这样做?为什么你关心其他程序员对你的课程做了什么?你负责让你的代码按照规范正常工作,如果另一个程序员想滥用它,那是他/她的问题,不是吗? 我怀疑你会找到一种防弹的方法来防止恶意用户的每一种可能的滥用。不如现在就放弃吧。 你今天很积极......这也是对以下问题的回答:python中是否存在私有变量和方法以及它们(不)存在的原因。 @DSM 我会测试你的“邪恶”;) 不值得。 “我在你的应用程序中入侵了你的课程并清除了我所有的数据”。是您按下手机上的静音按钮的地方,这样他们就不会听到您在想知道您是否可以得到报酬(很多)来解决它时大笑。 【参考方案1】:我觉得这个问题引发了一些深刻的困惑。私有变量不能阻止邪恶的“黑客”。它们与安全无关。他们在那里推广良好的编程实践,例如maintaining low coupling。
如果“邪恶的程序员”可以访问您的源代码,他或她就可以对它做任何他或她想做的事情。调用变量“私有”不会改变这一点。如果说邪恶的程序员试图破坏您在另一个系统上执行的程序……调用变量“私有”对您没有好处。它不会改变程序在内存中的存储和操作方式。它只是强制执行(以一种不必要的复杂方式 IMO)separation of concerns。
另外,值得注意的是,在正常情况下,您不必经历所有这些恶作剧......
MyClass.__dict__ =
MyClass.__dict__.__setitem__('_MyClass__protectedVariable','...but it is not')
...分配给受保护的变量。您甚至不必覆盖__dict__
。你可以这样做:
MyClass._MyClass__protectedVariable = '...but it is not'
因为它真的不是。受保护,我的意思是。名称修改的主要目的是防止namespace collisions。如果您只想要一个“私有”属性,只需在其前面加上一个下划线即可。期望您的用户尊重惯例,并期望您的滥用者无论您做什么都会打破它。
【讨论】:
在研究您的答案时,我注意到您提到的两个“恶作剧”有一个很大的不同:前者称为object.__dict__.__setitem__
,后者称为object.__setattr__
。这对整体结果并没有太大的影响,但我认为如果你有一个稍微奇特的系统(比如在这种情况下),那是值得一提的。无论如何,很好的答案,谢谢。
@Juha,好的,我明白你的意思了——我不清楚你在谈论“这种攻击”在你的自定义@987654329 @。我更改了上述内容以符合这种理解。【参考方案2】:
在 Python 中,您不能以这种方式“保护”属性。为什么你和你的来电者处于敌对关系?你和他需要在一些事情上达成一致,这就是其中之一。写更好的文档,和他成为更好的朋友。我不知道你真正的问题是什么,但它无法用代码解决。
Java 和 C++ 等其他语言提供与 private
等的分隔,但 Python 根本不提供。事后你不能把它锁上。
如果你告诉我们更多关于这个邪恶的程序员是谁,以及你和他为什么不同意你的代码应该如何使用,我们也许可以为你提供其他解决方案的想法。
【讨论】:
至少在 C++ 中,即使private
也可以通过一些不太依赖于平台的方式来规避 :)【参考方案3】:
AFAIK 在 Python 中并没有真正的方法可以做到这一点。无论您做什么,任何人都可以随时复制您的源代码并删除您的 hack,或者(在大多数情况下)从类继承并覆盖它,或者直接重新分配方法。
但是:你为什么这么关心?如果您将其命名为__whatever
,那么文档非常明确,如果用户对此感到困惑,那么发生的任何不好的事情都是他们自己该死的错。
【讨论】:
【参考方案4】:对于这种数据更改,Python 并不是很保护。但这被视为一个特点。也许`final` keyword equivalent for variables in Python? 上关于常量/决赛的不同问题会有所帮助。 回答您的问题:可能无法保护您的类中的数据不被操纵,该类在同一个可执行文件中使用外部代码运行。您很可能需要将数据存储在单独的进程中,并提供某种 api 来与外部进程交换数据。
【讨论】:
以上是关于如何保护python类变量免受邪恶程序员的侵害?的主要内容,如果未能解决你的问题,请参考以下文章