[Python-Dev] In defense of Capabilities [was: doc for new restricted execution design for Python]

Brett Cannon brett at python.org
Fri Jul 7 18:56:33 CEST 2006


On 7/6/06, Talin <talin at acm.org> wrote:
>
> Brett Cannon wrote:
> > On 7/5/06, Talin <talin at acm.org> wrote:
> >> Transitioning from the checked to the unchecked state could only be
> done
> >> via C code. So the 'file' wrapper, for example, would switch over to
> the
> >> unchecked interpreter before calling the actual methods of 'file'. That
> >> C wrapper might also check the current permission state to see what
> >> operations were legal.
> >
> > So add the proper checks in Python/ceval.c:call_function() to check for
> > this
> > flag on every object passed in that is called?
>
> Right. I also realized that you would need to add code that propagates
> the checked bit from the class to any instances of the class. So
> whenever you call a class to create an object, if the class has the
> checked bit, the instance will have it set as well.
>
> >> So essentially, what I propose is to define a simple security primitive
> >> - which essentially comes down to checking a single bit - and use that
> >> as a basis to create more complex and subtle security mechanisms.
> >
> > Right, but it does require that the proper verification function be
> turned
> > on so that the permission bit on 'file' is checked.  It kind of seems
> like
> > 'rexec' and its f_restricted flag it set on execution frames, except you
> > are
> > adding an object-level flag as well.
> >
> > Either way, the trick is not fouling up switching between the two
> checking
> > functions.
> >
> > -Brett
>
> I wasn't aware of how rexec worked, but that seems correct to me.
>
> Given a 'restricted' flag on a stack frame, and one on the object as
> well, then the code for checking for permission violations is nothing
> more than:
>
>     if (object.restricted && exec_frame.restricted)
>         raise SecurityException
>
> In particular, there's no need to call a function to check a "permission
> level" or "access rights" or anything of the sort - all that stuff is
> implemented at a higher level.
>
> By making the check very simple, it can also be made very fast. And by
> making it fast, we can afford to call it a lot - for every operation in
> fact.
>
> And if we can call it for every operation, then we don't have to spend
> time hunting down all of the possible loopholes and ways in which 'file'
> or other restricted objects might be accessed.


Not true.  You have to set this object restriction flag, right?  What
happens if you don't set it on all of the proper classes/types?  You end up
in the exact same situation you are with crippling; making sure you cover
your ass with what you flag as  unsafe else you risk having something get
passed you.

Originally I had thought to simply add a check like the above into the
> interpreter. However, that would mean that *all* code, whether
> restricted or not, would have to pay the (slight) performance penalty of
> checking that flag. So instead, I thought it might be more efficient to
> have two different code paths, one with the check and one without. But
> all this is based on profound ignorance of the interpreter - there might
> be a hundred other, better ways to do this without having to create two
> versions of ceval.


Yeah, keep it simple, especially when it comes to ceval.c .

Another interesting think about the check bit idea is that you can set
> it on any kind of object. For example, you could set it on individual
> methods of a class rather than the class as a whole. However, that's
> probably needlessly elaborate, since fine-grained access control will be
> much more elegantly achieved via trusted wrappers.


Yeah, that seems a bit extreme.

-Brett
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.python.org/pipermail/python-dev/attachments/20060707/caeaa100/attachment.html 


More information about the Python-Dev mailing list