How to protect python class variables from an evil programmer?

How can I protect my variables from this kind of attack:

MyClass.__dict__ = {}
MyClass.__dict__.__setitem__('_MyClass__protectedVariable','...but it is not')

The above changes the dictionary of variables, and after that it runs the childs game to change all the variables. The top line is crucial for this. The above does not work if your dictionary is __setitem__modified as shown below).

I want to force the user to use my method setProtectedVariable(value)to change the variable, but I did not seem to find a way to do this in Python 2.7. Any ideas?

I also appreciate if you find other similar holes from the code below (I noticed that I should also add the file name and line number to my inspect.stackcheck in myDict.__setitem__).

This is what I have tried so far:

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()  
+5
4

, , . , "". . , , .

" " , , . "private" . - , ... "private" . , . ( ) .

, , ...

MyClass.__dict__ = {}
MyClass.__dict__.__setitem__('_MyClass__protectedVariable','...but it is not')

... var. __dict__. :

MyClass._MyClass__protectedVariable = '...but it is not'

. , . - . "private", . , , , .

+18

Python "" . ? , . , . , , .

, Java ++, private .., Python . .

, , , , .

+8

AFAIK Python. , , ( ) , , .

: ? __whatever , , , - , , .

+7

Python does not really protect this kind of data modification. But this is considered a feature. Maybe another question about constants / finals in the `final` key equivalent for variables in Python? . To answer your question: there is probably no way to protect data from manipulations in your class working with external code in the same executable file. Most likely, you will need to store your data in a separate process and provide some kind of api for exchanging data with a foreign process.

+3
source

All Articles