On 7/6/06, Talin <[EMAIL PROTECTED]> wrote:
Brett Cannon wrote:
> On 7/5/06, Talin <[EMAIL PROTECTED]> 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
_______________________________________________
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

Reply via email to