[Python-Dev] Security capabilities in Python
I would like to experiment with security based on Python references as security capabilities. Unfortunatly, there are several problems that make Python references invalid as capabilities: * There is no way to create secure proxies because there are no private attributes. * Lots of Python objects are reachable unnecessarily breaking the principle of least privelege (i.e: object.__subclasses__() etc.) I was wondering if any such effort has already begun or if there are other considerations making Python unusable as a capability platform? (Please cc the reply to my email) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Security capabilities in Python
You might take a look at zope.security: http://svn.zope.org/Zope3/trunk/src/zope/security/ It isn't a capability-based system, but it does address similar problems and might have some useful ideas. See the README.txt and untrustedinterpreter.txt. Jim Eyal Lotem wrote: I would like to experiment with security based on Python references as security capabilities. Unfortunatly, there are several problems that make Python references invalid as capabilities: * There is no way to create secure proxies because there are no private attributes. * Lots of Python objects are reachable unnecessarily breaking the principle of least privelege (i.e: object.__subclasses__() etc.) I was wondering if any such effort has already begun or if there are other considerations making Python unusable as a capability platform? (Please cc the reply to my email) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/jim%40zope.com -- Jim Fulton mailto:[EMAIL PROTECTED] Python Powered! CTO (540) 361-1714http://www.python.org Zope Corporation http://www.zope.com http://www.zope.org ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Security capabilities in Python
On Fri, 8 Apr 2005, Eyal Lotem wrote: > I would like to experiment with security based on Python references as > security capabilities. This is an interesting and worthwhile thought. Several people (including myself) have talked about the possibility of doing this in the past. I believe the two problems you mention can be addressed without modifying the Python core. > * There is no way to create secure proxies because there are no > private attributes. Attributes are not private, but local variables are. If you use lexical scoping to restrict variable access (as one would in Scheme, E, etc.) you can create secure proxies. See below. > * Lots of Python objects are reachable unnecessarily breaking the > principle of least privelege (i.e: object.__subclasses__() etc.) True. However, Python's restricted execution mode prevents access to these attributes, allowing you to enforce encapsulation. (At least, that is part of the intent of restricted execution mode, though currently we do not make official guarantees about it.) Replacing __builtins__ activates restricted execution mode. Here is a simple facet function. def facet(target, allowed_attrs): class Facet: def __repr__(self): return '' % (allowed_attrs, target) def __getattr__(self, name): if name in allowed_attrs: return getattr(target, name) raise NameError(name) return Facet() def restrict(): global __builtins__ __builtins__ = __builtins__.__dict__.copy() # Here's an example. list = [1, 2, 3] immutable_facet = facet(list, ['__getitem__', '__len__', '__iter__']) # Here's another example. class Counter: def __init__(self): self.n = 0 def increment(self): self.n += 1 def value(self): return self.n counter = Counter() readonly_facet = facet(counter, ['value']) If i've done this correctly, it should be impossible to alter the contents of the list or the counter, given only the immutable_facet or the readonly_facet, after restrict() has been called. (Try it out and let me know if you can poke holes in it...) The upshot of all this is that i think you can do secure programming in Python if you just use a different style. Unfortunately, this style is incompatible with the way classes are usually written in Python, which means you can't safely use much of the standard library, but i believe the language itself is not fatally flawed. -- ?!ng ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Security capabilities in Python
On Sat, 9 Apr 2005 00:13:40 -0500 (CDT), Ka-Ping Yee <[EMAIL PROTECTED]> wrote: >On Fri, 8 Apr 2005, Eyal Lotem wrote: > > I would like to experiment with security based on Python references as > > security capabilities. > > This is an interesting and worthwhile thought. Several people > (including myself) have talked about the possibility of doing > this in the past. I believe the two problems you mention can be > addressed without modifying the Python core. > > > * There is no way to create secure proxies because there are no > > private attributes. > > Attributes are not private, but local variables are. If you use > lexical scoping to restrict variable access (as one would in > Scheme, E, etc.) you can create secure proxies. See below. > > > * Lots of Python objects are reachable unnecessarily breaking the > > principle of least privelege (i.e: object.__subclasses__() etc.) > > True. However, Python's restricted execution mode prevents access > to these attributes, allowing you to enforce encapsulation. (At > least, that is part of the intent of restricted execution mode, > though currently we do not make official guarantees about it.) > Replacing __builtins__ activates restricted execution mode. > > Here is a simple facet function. > > def facet(target, allowed_attrs): > class Facet: > def __repr__(self): > return '' % (allowed_attrs, target) > def __getattr__(self, name): > if name in allowed_attrs: > return getattr(target, name) > raise NameError(name) > return Facet() > > def restrict(): > global __builtins__ > __builtins__ = __builtins__.__dict__.copy() > > # Here's an example. > > list = [1, 2, 3] > immutable_facet = facet(list, ['__getitem__', '__len__', '__iter__']) > > # Here's another example. > > class Counter: > def __init__(self): > self.n = 0 > > def increment(self): > self.n += 1 > > def value(self): > return self.n > > counter = Counter() > readonly_facet = facet(counter, ['value']) > > If i've done this correctly, it should be impossible to alter the > contents of the list or the counter, given only the immutable_facet > or the readonly_facet, after restrict() has been called. > > (Try it out and let me know if you can poke holes in it...) > > The upshot of all this is that i think you can do secure programming > in Python if you just use a different style. Unfortunately, this > style is incompatible with the way classes are usually written in > Python, which means you can't safely use much of the standard library, > but i believe the language itself is not fatally flawed. > Does using the gc module to bypass this security count? If so: [EMAIL PROTECTED]:~$ python -i facet.py >>> import gc >>> c = readonly_facet.__getattr__.func_closure[1] >>> r = gc.get_referents(c)[0] >>> r.n = 'hax0r3d' >>> readonly_facet.value() 'hax0r3d' >>> This is the easiest way of which I know to bypass the use of cells as a security mechanism. I believe there are other more involved (and fragile, probably) ways, though. Jp ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Security capabilities in Python
Jp Calderone <[EMAIL PROTECTED]> writes: > Does using the gc module to bypass this security count? If so: > > [EMAIL PROTECTED]:~$ python -i facet.py > >>> import gc > >>> c = readonly_facet.__getattr__.func_closure[1] > >>> r = gc.get_referents(c)[0] > >>> r.n = 'hax0r3d' > >>> readonly_facet.value() > 'hax0r3d' > >>> > > This is the easiest way of which I know to bypass the use of cells > as a security mechanism. I believe there are other more involved > (and fragile, probably) ways, though. The funniest I know is part of PyPy: def extract_cell_content(c): """Get the value contained in a CPython 'cell', as read through the func_closure of a function object.""" # yuk! this is all I could come up with that works in Python 2.2 too class X(object): def __eq__(self, other): self.other = other x = X() x_cell, = (lambda: x).func_closure x_cell == c return x.other It would be unfortunate for PyPy (and IMHO, very un-pythonic) if this process became impossible. Cheers, mwh -- Java sucks. [...] Java on TV set top boxes will suck so hard it might well inhale people from off their sofa until their heads get wedged in the card slots. --- Jon Rabone, ucam.chat ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Security capabilities in Python
On Apr 9, 2005, at 2:13 PM, Michael Hudson wrote: The funniest I know is part of PyPy: def extract_cell_content(c): """Get the value contained in a CPython 'cell', as read through the func_closure of a function object.""" # yuk! this is all I could come up with that works in Python 2.2 too class X(object): def __eq__(self, other): self.other = other x = X() x_cell, = (lambda: x).func_closure x_cell == c return x.other It would be unfortunate for PyPy (and IMHO, very un-pythonic) if this process became impossible. It would be quite fortunate if you didn't have to do all that, and cell just had a "value" attribute, though. James ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Security capabilities in Python
On Sat, 9 Apr 2005, Jp Calderone wrote: > Does using the gc module to bypass this security count? If so: > > [EMAIL PROTECTED]:~$ python -i facet.py > >>> import gc > >>> c = readonly_facet.__getattr__.func_closure[1] > >>> r = gc.get_referents(c)[0] > >>> r.n = 'hax0r3d' > >>> readonly_facet.value() > 'hax0r3d' > >>> You can't get func_closure in restricted mode. (Or at least, i can't, using the Python included with Mac OS 10.3.8.) >>> restrict() >>> readonly_facet.__getattr__.func_closure Traceback (most recent call last): File "", line 1, in ? RuntimeError: restricted attribute >>> Even though this particular example doesn't work in restricted mode, it's true that the gc module violates capability discipline, and you would have to forbid its import. In any real use case, you would have to restrict imports anyway to prevent access to sys.modules or loading of arbitrary binaries. For a version that restricts imports, see: http://zesty.ca/python/facet.py Let me know if you figure out how to defeat that. (This is a fun exercise, but with a potential purpose -- it would be nice to have a coherent story on this for Python 3000, or maybe even Python 2.x.) -- ?!ng ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Security capabilities in Python
On Sat, 9 Apr 2005, Michael Hudson wrote: > The funniest I know is part of PyPy: > > def extract_cell_content(c): > """Get the value contained in a CPython 'cell', as read through > the func_closure of a function object.""" > # yuk! this is all I could come up with that works in Python 2.2 too > class X(object): > def __eq__(self, other): > self.other = other > x = X() > x_cell, = (lambda: x).func_closure > x_cell == c > return x.other That's pretty amazing. > It would be unfortunate for PyPy (and IMHO, very un-pythonic) if this > process became impossible. Not a problem. func_closure is already a restricted attribute. IMHO, the clean way to do this is to provide a built-in function to get the cell content in a more direct and reliable way, and then put that in a separate module with other interpreter hacks. That both makes it easier to do stuff like this, and easier to prevent it simply by forbidding import of that module. -- ?!ng ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Security capabilities in Python
Ka-Ping Yee wrote: On Sat, 9 Apr 2005, Jp Calderone wrote: Does using the gc module to bypass this security count? If so: [EMAIL PROTECTED]:~$ python -i facet.py >>> import gc >>> c = readonly_facet.__getattr__.func_closure[1] >>> r = gc.get_referents(c)[0] >>> r.n = 'hax0r3d' >>> readonly_facet.value() 'hax0r3d' >>> You can't get func_closure in restricted mode. (Or at least, i can't, using the Python included with Mac OS 10.3.8.) >>> restrict() >>> readonly_facet.__getattr__.func_closure Traceback (most recent call last): File "", line 1, in ? RuntimeError: restricted attribute >>> Even though this particular example doesn't work in restricted mode, it's true that the gc module violates capability discipline, and you would have to forbid its import. In any real use case, you would have to restrict imports anyway to prevent access to sys.modules or loading of arbitrary binaries. For a version that restricts imports, see: http://zesty.ca/python/facet.py Let me know if you figure out how to defeat that. you should probably search the list and look at my old attacks against restricted execution, there's reason why is not much supported anymore. One can still try to use it but needs to be extremely careful or use C defined proxies... etc. (This is a fun exercise, but with a potential purpose -- it would be nice to have a coherent story on this for Python 3000, or maybe even Python 2.x.) -- ?!ng ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/pedronis%40strakt.com ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Security capabilities in Python
On Apr 9, 2005, at 5:37 PM, Ka-Ping Yee wrote: Let me know if you figure out how to defeat that. You can protect against this, too, but it does show that it's *really* hard to get restricting code right...I'm of the opinion that it's not really worth it -- you should just use OS protections. untrusted_module.py: class foostr(str): def __eq__(self, other): return True def have_at_it(immutable_facet, readonly_facet): getattr(immutable_facet, foostr('append'))(5) print immutable_facet James ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Security capabilities in Python
On Sat, 9 Apr 2005, James Y Knight wrote: > You can protect against this, too, but it does show that it's *really* > hard to get restricting code right... Good point. If you can't trust ==, then you're hosed. > I'm of the opinion that it's not > really worth it -- you should just use OS protections. This i disagree with, however. OS protections are a few orders of magnitude more heavyweight and vastly more error-prone than using a language with simple, clear semantics. Predictable code behaviour is good. -- ?!ng ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Security capabilities in Python
James Y Knight <[EMAIL PROTECTED]> writes: > On Apr 9, 2005, at 2:13 PM, Michael Hudson wrote: > >> The funniest I know is part of PyPy: >> >> def extract_cell_content(c): >> """Get the value contained in a CPython 'cell', as read through >> the func_closure of a function object.""" >> # yuk! this is all I could come up with that works in Python 2.2 >> too >> class X(object): >> def __eq__(self, other): >> self.other = other >> x = X() >> x_cell, = (lambda: x).func_closure >> x_cell == c >> return x.other >> >> It would be unfortunate for PyPy (and IMHO, very un-pythonic) if this >> process became impossible. > > It would be quite fortunate if you didn't have to do all that, and > cell just had a "value" attribute, though. Indeed. The 2.2 compatibility issue remains, though. Cheers, mwh -- Presumably pronging in the wrong place zogs it. -- Aldabra Stoddart, ucam.chat ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Security capabilities in Python
It may be really hard to get it right, unless we are overlooking some simple solution.I disagree that we should "just use OS protections".The reason I am interested in Pythonic protection is because it is so much more powerful than OS protections. The capability model is much more powerful than the ACL model used by all OS's these days, and allows for interesting security concepts.What about implementing the facet in C? This could avoid the class of problems you have just mentioned.On Apr 9, 2005 2:02 PM, James Y Knight <[EMAIL PROTECTED]> wrote:> On Apr 9, 2005, at 5:37 PM, Ka-Ping Yee wrote:> > Let me know if you figure out how to defeat that.> > You can protect against this, too, but it does show that it's *really*> hard to get restricting code right...I'm of the opinion that it's not> really worth it -- you should just use OS protections.> > untrusted_module.py:> > class foostr(str):> def __eq__(self, other):>return True> > def have_at_it(immutable_facet, readonly_facet):>getattr(immutable_facet, foostr('append'))(5)>print immutable_facet> > James___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Security capabilities in Python
On Sun, 10 Apr 2005, Eyal Lotem wrote: > It may be really hard to get it right, unless we are overlooking some simple > solution. To "get it right", you at least need to know exactly what your operators mean. I messed up because i failed to realize that '==' can be redefined, and 'in' depends on '==' to work properly. > What about implementing the facet in C? This could avoid the class of > problems you have just mentioned. I don't think that's a good solution. A facet is just one basic programming pattern that you can build in a capability system; it would be silly to have to go back to C every time you wanted to build some other construct. A better way would be to start with capabilities that behave simply and correctly; then you can build whatever you want. -- ?!ng ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Security capabilities in Python
Eyal Lotem wrote: I would like to experiment with security based on Python references as security capabilities. Unfortunatly, there are several problems that make Python references invalid as capabilities: * There is no way to create secure proxies because there are no private attributes. * Lots of Python objects are reachable unnecessarily breaking the principle of least privelege (i.e: object.__subclasses__() etc.) I was wondering if any such effort has already begun or if there are other considerations making Python unusable as a capability platform? You might want to have a look at mxProxy objects. These were created to provide secure wrappers around Python objects with a well-defined access mechanism, e.g. by defining a list of methods/attributes which can be accessed from the outside or by creating a method which then decides whether access is granted or not: http://www.egenix.com/files/python/mxProxy.html Note that the new-style classes may have introduced some security leaks. If you find any, please let me know. PS: A nice side-effect of the these proxy objects is that you can create weak-reference to all Python objects (not just those that support the protocol). -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Apr 18 2005) >>> Python/Zope Consulting and Support ...http://www.egenix.com/ >>> mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ >>> mxODBC, mxDateTime, mxTextTools ...http://python.egenix.com/ ::: Try mxODBC.Zope.DA for Windows,Linux,Solaris,FreeBSD for free ! ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com