2012-02-07 33 views
5

Làm thế nào tôi có thể bảo vệ biến tôi từ loại tấn công này:Làm thế nào để bảo vệ các biến lớp python từ một lập trình độc ác?

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

Trên đây thay đổi từ điển khác nhau và sau đó nó là Childs chơi để thay đổi tất cả các biến. Các dòng trên là rất quan trọng cho việc này để làm việc. Ở trên không hoạt động nếu từ điển của bạn là __setitem__ được tinh chỉnh như dưới đây).

Tôi muốn buộc người dùng sử dụng phương thức setProtectedVariable(value) của mình để thay đổi biến, nhưng dường như tôi không tìm cách làm điều đó trong Python 2.7. Bất kỳ ý tưởng?

Tôi cũng đánh giá cao nếu bạn tìm thấy các lỗ tương tự khác từ mã bên dưới (Tôi nhận thấy rằng tôi cũng nên thêm tên tệp và số dòng vào số inspect.stack của mình tại myDict.__setitem__).

Đây là những gì tôi đã cố gắng cho đến nay:

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

Tại sao bạn muốn thực hiện việc này? Tại sao bạn quan tâm đến những gì một lập trình viên khác làm với lớp học của bạn? Bạn chịu trách nhiệm làm cho mã của bạn hoạt động đúng theo thông số kỹ thuật, nếu một lập trình viên khác muốn lạm dụng nó là vấn đề của anh ta, phải không? –

+0

Tôi nghi ngờ bạn sẽ tìm thấy một cách chống đạn để bảo vệ chống lại mọi hành vi lạm dụng có thể có của một người dùng độc hại. Bạn có thể bỏ cuộc ngay bây giờ. – NPE

+1

Bạn đang tích cực ngày hôm nay ... Đây cũng là một câu trả lời cho câu hỏi: Do biến cá nhân và phương pháp tồn tại trong python và tại sao họ (không) tồn tại. – Juha

Trả lời

18

Tôi cảm thấy có sự nhầm lẫn sâu sắc thúc đẩy câu hỏi này. Các biến riêng tư không tồn tại để giữ "tin tặc" tà ác. Họ không có gì để làm với an ninh. Họ đang ở đó để quảng cáo các phương pháp lập trình tốt như maintaining low coupling.

Nếu một "nhà lập trình độc ác" có quyền truy cập vào mã nguồn của bạn, họ có thể làm bất cứ điều gì họ muốn với nó. Gọi một biến "riêng tư" sẽ không thay đổi điều đó. Nếu lập trình viên ác nói là cố gắng thỏa hiệp chương trình của bạn thực hiện trên một hệ thống khác ... gọi một biến "tư nhân" sẽ làm bạn không tốt. Nó không thay đổi bất cứ điều gì về cách chương trình được lưu trữ và thao tác trong bộ nhớ. Nó chỉ thực thi (theo cách phức tạp không cần thiết IMO) separation of concerns.

Ngoài ra, nó có giá trị lưu ý rằng điều kiện bình thường bạn không cần phải đi qua tất cả những tinh quái ...

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

... để gán cho một var bảo vệ. Bạn thậm chí không phải ghi đè lên __dict__. Bạn chỉ có thể làm điều này:

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

Nguyên nhân là thực sự không. Được bảo vệ, ý tôi là. Mục đích chính của mangling tên là để ngăn chặn namespace collisions. Nếu bạn chỉ muốn thuộc tính "riêng tư", chỉ cần thêm tiền tố vào một dấu gạch dưới đơn. Mong đợi người dùng của bạn tôn trọng quy ước và mong người ngược đãi của bạn phá vỡ nó bất kể bạn làm gì.

+0

Trong khi tôi đang nghiên cứu câu trả lời của bạn, tôi nhận thấy rằng hai" shenanigans "mà bạn đề cập có một sự khác biệt lớn. .__ dict __.__ setitem__' và sau đó gọi 'đối tượng .__ setattr__'. Điều này không tạo ra sự khác biệt lớn trong kết quả tổng thể, nhưng tôi nghĩ là đáng nói nếu bạn có hệ thống hơi kỳ lạ (như trong trường hợp này). Dù sao, câu trả lời tốt, cảm ơn. – Juha

+0

@ Juha, OK, tôi hiểu ý của bạn là gì - không rõ ràng với tôi rằng bạn đang nói về "kiểu tấn công này" _on tùy chỉnh của bạn_ '__setattr__'. Tôi đã thay đổi ở trên để hợp tác với sự hiểu biết đó. – senderle

7

AFAIK không phải thực sự là một cách để làm điều này trong Python. Không có vấn đề gì bạn làm, bất cứ ai cũng có thể sao chép nguồn của bạn và loại bỏ hack của bạn, hoặc (trong hầu hết các trường hợp) hoặc kế thừa từ lớp và ghi đè nó hoặc chỉ trực tiếp gán lại các phương thức.

Nhưng: tại sao bạn quan tâm nhiều đến vậy? Nếu bạn đặt tên nó là __whatever đó là tài liệu rất rõ ràng rằng nếu người dùng mess với điều này, bất cứ điều gì xấu xảy ra là lỗi damn của riêng mình.

8

Trong Python, bạn không thể "bảo vệ" thuộc tính theo cách này. Tại sao bạn trong một mối quan hệ đối kháng với người gọi của bạn? Bạn và anh ta cần phải đồng ý về một số thứ, đây là một trong số họ. Viết tài liệu tốt hơn, trở thành bạn bè tốt hơn với anh ấy. Tôi không biết vấn đề thực sự của bạn là gì, nhưng nó không thể được giải quyết bằng mã.

Các ngôn ngữ khác như Java và C++ cung cấp sự tách biệt với private và vân vân, nhưng Python đơn giản là không. Bạn không thể buông nó ra sau khi thực tế.

Nếu bạn cho chúng tôi biết thêm về lập trình viên độc ác này là ai và tại sao bạn không đồng ý về cách sử dụng mã của bạn, chúng tôi có thể cung cấp cho bạn các ý tưởng khác cho giải pháp.

+6

Ít nhất là trong C++, ngay cả trong 'C++' có thể được phá vỡ theo một số cách không phụ thuộc vào nền tảng khủng khiếp :) –

3

Python không bảo vệ liên quan đến loại thay đổi dữ liệu này. Nhưng đây được xem là một tính năng. Có lẽ một câu hỏi khác về hằng số/trận chung kết tại `final` keyword equivalent for variables in Python? là một số trợ giúp. Để trả lời câu hỏi của bạn: Có lẽ không có cách nào để bảo vệ dữ liệu khỏi các thao tác trong lớp của bạn đang chạy với mã nước ngoài trong cùng một tệp thực thi. Bạn có lẽ sẽ cần lưu trữ dữ liệu của bạn trong một quy trình riêng biệt và cung cấp một số loại api để trao đổi dữ liệu với quy trình nước ngoài.

Các vấn đề liên quan