[Zope-dev] Re: Zope security alert and hotfix product...
Brian Lloyd
Brian@digicool.com
Mon, 14 Aug 2000 10:12:52 -0400
> > The issue involves the fact that the getRoles method of
> user objects
> > contained in the default UserFolder implementation returns
> a mutable
> > Python type. Because the mutable object is still
> associated with the
> > persistent User object, users with the ability to edit DTML could
> > arrange to give themselves extra roles for the duration of
> a single
> > request by mutating the roles list as a part of the request
> >processing.
>
> OK, so I can exploit this with something similar to
> user.getRoles().append('A Role That I Dont Have')
>
> But, why isnt the append method covered by the new
> inaccessible-by-default 2.2 security rules?
Back when we were considering how much tightening would
be considered acceptable in one dose, we ended up not
preventing access to methods of mutable python types
([], {}). The main reason that we were aware of a fair
number of people using this (including one or two internal
things) for legitimate things:
<dtml-var "REQUEST.set('some_stuff', [])">
<dtml-in other_stuff>
<dtml-call "some_stuff.append(_['sequence-item'])">
</dtml-in>
etc. So we made the decision not to break those things.
The real problem, of course, is that the Zope APIs (and
the APIs of add on products) should not return references
to mutable subobjects. If an API method must return a
mutable Python type, it should return a copy rather than
a direct reference:
def myMethod(self):
# self.stuff is a dict
# dont do this!
return self.stuff
# do this instead
return self.stuff.copy()
# or if stuff is a list either do:
return self.stuff[:]
# or
return tuple(self.stuff)
Now - should methods of mutable types be off-limits in the
future? I'm not sure that the jury is in yet on that. Consider
that PythonMethods (that soon will be part of the core) play
by basically the same rules as dtml. While it might be pretty
easy to argue that the list-juggling in my DTML example above
is bad practice, I think most people would expect to be able
to do:
mylist=[]
mylist.append('one')
return mylist
...in a PythonMethod and have it work. I don't think it would
be acceptable for 'append' to be off-limits in this case, so
the alternative is that the security machinery would somehow
have to be able to distinguish mutables created by the user
from those obtained from the secure environment. That would
probably mean that API code would have to make some sort of
security assertions about mutables they returned. Exactly
how that would work I don't know...
Brian Lloyd brian@digicool.com
Software Engineer 540.371.6909
Digital Creations http://www.digicool.com