Jeremy Hylton wrote:
On Sat, 2003-03-08 at 07:27, Ben Laurie wrote:
Bound methods are not capabilities unless they are secured. It seems the correct way to do this is to use restricted execution, and perhaps some other tricks. What I am trying to nail down is exactly what needs doing to get us from where we are now to where capabilities actually work. As I understand it, what is needed is:
a) Fix restricted execution, which is in a state of disrepair
b) Override import, open (and other stuff? what?)
c) Wrap or replace some of the existing libraries, certify that others are "safe"
It looks to me like a and b are shared with proxies, and c would be different, by definition. Is there anything else? Am I on the wrong track?
I have been trying to argue, though I feel a bit muddled at times, that the proxy approach eliminates the need for rexec and makes it possible to build a "restricted environment" without relying on the rexec code in the interpreter.
Any security scheme needs some kind of information hiding to guarantee that untrusted code does not break into the representation of an object, so that, for example, an object can be used as a capability. I think we've discussed two different ways to implement information hiding.
The rexec approach is to add code to the interpreter to disable certain introspection features when running untrusted code.
The proxy approach is to wrap protected objects in proxies before passing them to untrusted code.
I think both techniques achieve the same end, but with different limitations. I prefer the proxy approach because it is more self contained. The rexec approach requires that all developers working in the core on introspection features be aware of security issues. The security kernel ends up being most of the core interpreter -- anything that can introspection on objects. The proxy approach is to create an object that specifically disables introspection by not exposing internals to the core. We need to do some more careful analysis to be sure that proxies really achieve the goal of information hiding.
I think another benefit of proxies vs. rexec is that untrusted code can still use all of the standard introspection features when dealing with objects it creates itself. Code running in rexec can't use any introspective feature, period, because all those features are disabled. With the proxy approach, introspection is only disabled on protected objects.
These are all good points.
Proxies have a dark side though. They sometimes trip up standard facilities in Python that either depend on specific types or on identity comparisons. With a bit of effort, proxies can be made highly transparent, but they change an object's type and id. For example, you can't proxy exceptions without breaking exception handling. In Zope, we rely on restricted execution to prevent certian kinds of introspection on exceptions and exception classes. In Zope, we also don't proxy None, because None is usually checked for identity. We also don't proxy strings, and numbers.
I think I agree that you could build a restricted environment with proxies alone, but, to do so, you would need to make Python far more proxy aware. I think that the language would need to be aware of proxies at a far deeper level.