Jeremy Hylton wrote:
On Mon, 2003-03-03 at 08:42, Ben Laurie wrote:
I think the fundamental problem for rexec is that you don't have a security kernel. The code for security gets scatter throughout the interpreter. It's hard to have much assurance in the security when its tangled up with everything else in the language.
You can use a proxy for an object to deal with goal #1 above -- enforce an interface for an object. I think about this much like a hardware capability architecture. The protected objects live in the capability segment and regular code can't access them directly. The only access is via a proxy object that is bound to the capability.
Regardless of proxy vs. rexec, I'd be interested to hear what you think about a sound way to engineer a secure Python.
I'm told that proxies actually rely on rexec, too. So, I guess whichever approach you take, you need rexec.
The problem is that although you can think about proxies as being like a segmented architecture, you have to enforce that segmentation. And that means doing so throughout the interpreter, doesn't it? I suppose it might be possible to abstract things in some way to make that less widespread, but probably not without having an adverse impact on speed.
The boundary between the interpreter and the proxy is the generic type object API. The Python code does not know anything about the representation of a proxy object, except that it is a PyObject *. As a result, the only way to invoke operations on its is to go through the various APIs in the type object's table of function pointers.
There are surely limits to how far the separation can go. I expect you can't inherit from a proxy for a class, such that the base class is in a different protection domain than the subclass. But I think there are fewer ad hoc restrictions than there are in rexec.
I think this provides a pretty clean separation of concerns, even if the proxy object were a standard part of Python. The only code that should manipulate the proxy representation is its implementation. The only other step would be to convince yourself that Python does not inspect arbitrary parts of a concrete PyObject * in an unsafe way.
I'm obviously missing something - surely you can say pretty much exactly the same thing about a bound method, just replace "type object" with "PyMethodObject"? And in either case, you also need to restrict access to the underlying libraries and (presumably) some of the builtin functions? BTW, Guido pointed out to me that I'm causing confusion by saying "rexec" when I really mean "restricted execution". In short, it seems to me that proxies and capabilities via bound methods both do the same basic thing: i.e. prevent inspection of what is behind the capability/proxy. Proxies add access control to decide whether you get to use them or not, whereas in a capability system simple posession of the capability is sufficient (i.e. they are like a proxy where the security check always says "yes"). You do access control using capabilities, instead of inside them. Am I not understanding proxies? Cheers, Ben. -- http://www.apache-ssl.org/ben.html http://www.thebunker.net/ "There is no limit to what a man can do or how far he can go if he doesn't mind who gets the credit." - Robert Woodruff