Python object encapsulation security
Question: I have a question, and my decision in choosing Python as a possible language
for a bigger project depends on the answer - which I cannot come up with
myself:

We all know that Python has no _real_ object encapsulation, so there is
nothing like "private" properties of an object. Regarding this issue, Guido
van Rossum says that one can access hidden parts of a foreign object without
being "allowed" to, with "we are all adults", "just don't do it". I can live
perfectly well with that, as long as the software I write is in my own hand,
so I am responsible for my own errors and just can try to avoid such things.

BUT - and here comes my question: What if I provide a plugin framework with
some plugins that have some extension points, and many of the plugins are by
OTHER people, maybe ones that I cannot trust completely.

How do I prevent exposing internals of my framework from being accessed by a
plugin?

Is there a way to achieve this, or is the only way to use Python having
confidence that no one will abuse my API?


Answer: You should never really rely on `private`, `public` etc for security (as in
"protection against malicious code and external threats"). They are meant as
something to keep the programmer from shooting himself in the foot, not as a
(computer) security measure. You can also easily access private member fields
of C++ objects, as long as you bypass static compiler checks and go straight
to the memory, but would you say that C++ lacks true encapsulation?

  * For **C++** , see <http://phoxis.org/2012/01/25/accessing-private-data-members-directly-outside-from-its-class-in-c/>
  * Same about the **JVM** (and thus **Java**): [How do I read a private field in Java?](http://stackoverflow.com/questions/1196192/how-do-i-read-a-private-field-in-java)
  * And (more or less) the same about **CLR** (i.e. **.NET**): [Does reflection breaks the idea of private methods, because private methods can be access outside of the class?](http://stackoverflow.com/questions/3300680/does-reflection-breaks-the-idea-of-private-methods-because-private-methods-can)

So you would never really use `private` or `protected` as a security measure
against malicious plugins in C++ nor Java, and I assume C# as well.

Your best bet is to run your plugins in a separate process and expose the core
API over IPC/RPC or even web service, or run them in a
[sandbox](https://www.google.com/search?q=sandboxed+python) (as per what
@MarkHildreth pointed out). Alternatively, you can set up a certification and
signing process for your plugins so that you can review and filter out
potentially malicious plugins before they even get distributed.

**NOTE:**

You can actually achieve true encapsulation using lexical closures:

    
    
    def Foo(param):
        param = [param]  # because `nonlocal` was introduced only in 3.x
        class _Foo(object):
            @property
            def param(self):
                return param[0]
            @param.setter
            def param(self, val):
                param[0] = val
        return _Foo()
    
    foo = Foo('bar')
    print foo.param  # bar
    foo.param = 'baz'
    print foo.param  # baz
    # no way to access `foo._param` or anything
    

...but even then, the value is actually still relatively easily accessible via
reflection:

    
    
    >>> foo.__class__.param.fget.__closure__[0].cell_contents[0] = 'hey'
    >>> foo.param
    'hey'
    

...and even if this weren't possible, we'd still be left with
[`ctypes`](http://docs.python.org/2/library/ctypes.html) which allows direct
memory access, bypassing any remaining cosmetic "restrictions":

    
    
    import ctypes
    arr = (ctypes.c_ubyte * 64).from_address(id(foo))
    

and now you can just assign to `arr` or read from it; although you'd have to
work hard to traverse pointers from there down to the actual memory location
where `.param` is stored, but it proves the point.

