2012-02-07 7 views
5

मैं कैसे हमले के इस प्रकार से मेरे चर की रक्षा कर सकते हैं:एक दुष्ट प्रोग्रामर से अजगर वर्ग चर की रक्षा कैसे करें?

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

ऊपर चर शब्दकोश बदलता है और उसके बाद यह सभी चर बदलने के लिए बच्चे की खेल है। काम करने के लिए ऊपरी रेखा महत्वपूर्ण है। उपरोक्त काम नहीं करता है यदि आपके शब्दकोश का __setitem__ नीचे जैसा tweaked है)।

मैं चर को बदलने के लिए उपयोगकर्ता को अपनी विधि setProtectedVariable(value) का उपयोग करने के लिए मजबूर करना चाहता हूं, लेकिन मुझे पाइथन 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() 
+5

आप ऐसा क्यों करना चाहते हैं? आप अपनी कक्षा के साथ एक और प्रोग्रामर क्या करते हैं परवाह क्यों करते हैं? आप spec के अनुसार अपना कोड सही तरीके से काम करने के प्रभारी हैं, अगर कोई अन्य प्रोग्रामर इसका दुरुपयोग करना चाहता है तो वह उसकी समस्या है, है ना? –

+0

मुझे संदेह है कि आपको एक दुर्भावनापूर्ण उपयोगकर्ता द्वारा हर संभव दुरुपयोग के खिलाफ सुरक्षा के लिए बुलेटप्रूफ तरीका मिलेगा। आप अब भी हार सकते हैं। – NPE

+1

आप आज सकारात्मक हो रहे हैं ... यह भी प्रश्न का उत्तर है: निजी चर और विधियों में पाइथन में मौजूद हैं और वे क्यों नहीं हैं (क्यों नहीं)। – Juha

उत्तर

18

मुझे लगता है कुछ गहरी इस सवाल को प्रेरित करने में भ्रम की स्थिति नहीं है। बुराई "हैकर्स" को दूर रखने के लिए निजी चर नहीं हैं। उनके पास सुरक्षा के साथ कुछ लेना देना नहीं है। वे maintaining low coupling जैसे अच्छे प्रोग्रामिंग प्रथाओं को बढ़ावा देने के लिए वहां हैं।

एक "बुराई प्रोग्रामर" अपने स्रोत कोड की पहुंच है, तो वह या वह जो कुछ भी वह या वह इसके साथ करना चाहता है कर सकते हैं। एक चर "कॉलिंग" को कॉल करने से वह नहीं बदलेगा। यदि कहा गया है कि बुरा प्रोग्रामर आपके प्रोग्राम को किसी अन्य सिस्टम पर निष्पादित करने की कोशिश कर रहा है ... एक परिवर्तनीय "निजी" को कॉल करने से आप कोई अच्छा नहीं करेंगे। यह प्रोग्राम को संग्रहीत करने और स्मृति में छेड़छाड़ के तरीके के बारे में कुछ भी नहीं बदलता है। यह सिर्फ लागू करता है (एक अनावश्यक जटिल तरीके से आईएमओ) separation of concerns

इसके अलावा, यह एक संरक्षित वर के लिए आवंटित करने के लिए ध्यान देने योग्य सामान्य परिस्थितियों में आप इन सभी धोखाधड़ी के माध्यम से जाने की जरूरत नहीं है कि है ...

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

...। आपको __dict__ को ओवरराइट करने की भी आवश्यकता नहीं है। कारण यह वास्तव में नहीं है

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

: तुम बस ऐसा कर सकते हैं। संरक्षित, मेरा मतलब है। नाम mangling का मुख्य उद्देश्य namespace collisions को रोकने के लिए है। यदि आप सिर्फ "निजी" विशेषता चाहते हैं, तो बस इसे एक अंडरस्कोर से उपसर्ग करें। अपने उपयोगकर्ताओं को सम्मेलन का सम्मान करने की अपेक्षा करें, और उम्मीद करें कि आपके दुर्व्यवहार करने वालों को इससे कोई फर्क नहीं पड़ता कि आप क्या करते हैं।

+0

जबकि मैं आपका जवाब पढ़ रहा था, मैंने देखा कि आपके द्वारा उल्लेख किए गए दो "शेनानिगन्स" में एक बड़ा अंतर है: पूर्व 'ऑब्जेक्ट' .__ dict __.__ setitem__' और बाद वाले कॉल 'ऑब्जेक्ट .__ setattr__'। इससे समग्र परिणाम में कोई बड़ा अंतर नहीं आता है, लेकिन मुझे लगता है कि अगर आपके पास थोड़ा विदेशी सिस्टम है (इस मामले में)। वैसे भी, अच्छा जवाब, धन्यवाद। – Juha

+0

@ जुहा, ठीक है, मैं देखता हूं कि आपका क्या मतलब है - यह मुझे स्पष्ट नहीं था कि आप "इस तरह के हमले" के बारे में बात कर रहे थे _ _ आपके अनुकूलित_ '__setattr__'। मैंने उस समझ के साथ उपरोक्त को कॉम्पोर्ट में बदल दिया। – senderle

7

AFAIK वहाँ वास्तव में अजगर में ऐसा करने का कोई तरीका नहीं है:

यह वही है मैं अब तक की कोशिश की है है। इससे कोई फर्क नहीं पड़ता कि आप क्या करते हैं, कोई भी हमेशा आपके स्रोत की प्रतिलिपि बना सकता है और अपने हैक्स को हटा सकता है, या (ज्यादातर मामलों में) या तो कक्षा से उत्तराधिकारी हो सकता है और इसे ओवरराइड कर सकता है या सीधे तरीकों को फिर से सौंप सकता है।

लेकिन: आप इतनी परवाह क्यों करते हैं? यदि आप इसे __whatever नाम देते हैं तो यह बहुत स्पष्ट दस्तावेज है कि यदि उपयोगकर्ता इसके साथ गड़बड़ करते हैं, तो जो भी बुरा होता है वह उनकी खुद की गलती है।

8

अजगर में, आप "रक्षा" नहीं कर सकते हैं इस तरह से जिम्मेदार बताते हैं। आप अपने कॉलर के साथ एक विरोधी संबंध में क्यों हैं? आपको और उसे कुछ चीजों पर सहमत होना चाहिए, यह उनमें से एक है। बेहतर दस्तावेज़ लिखें, उसके साथ बेहतर दोस्त बनें। मुझे नहीं पता कि आपकी असली समस्या क्या है, लेकिन इसे कोड के साथ हल नहीं किया जा सकता है।

जावा और सी जैसे अन्य भाषाओं ++ private साथ जुदाई की पेशकश और इतने पर है, लेकिन अजगर बस नहीं करता है। तथ्य के बाद आप इसे बोल्ट नहीं कर सकते हैं।

आप हमें जो इस बुराई प्रोग्रामर है के बारे में और अधिक बता, और तुम और वह कैसे अपने कोड इस्तेमाल किया जाना चाहिए के बारे में क्यों असहमत हैं, हम समाधान के लिए आप अन्य विचारों देने में सक्षम हो सकता है।

+6

कम से कम सी ++ में भी कुछ निजी प्लेटफार्म-निर्भर तरीकों में 'निजी' को बाधित किया जा सकता है :) –

3

अजगर डेटा परिवर्तन के इस प्रकार के बारे में बहुत रक्षात्मक नहीं है। लेकिन यह एक विशेषता माना जाता है। शायद `final` keyword equivalent for variables in Python? पर स्थिरांक/फाइनल के बारे में एक अलग सवाल कुछ मदद की है। अपने प्रश्न का उत्तर देने के लिए: संभवतः एक ही निष्पादन योग्य में विदेशी कोड के साथ चलने वाली कक्षा में हेरफेर के खिलाफ डेटा की रक्षा करने का कोई तरीका नहीं है। आपको शायद अपने डेटा को एक अलग प्रक्रिया में स्टोर करने की आवश्यकता होगी और विदेशी प्रक्रिया के साथ डेटा का आदान-प्रदान करने के लिए किसी प्रकार का एपीआई प्रदान करना होगा।

संबंधित मुद्दे