[Zope-dev] Re: Strange security issue with Zope 2.8.1
Florent Guillaume
fg at nuxeo.com
Thu Sep 29 13:16:38 EDT 2005
Jens Vagelpohl wrote:
> I have found a strange security issue with Zope 2.8.1 that seems to
> stem from code not doing what it was supposed to do in Zope 2.7.x, but
> which works in 2.8.1 and then causes other side effects in code that
> relied on the broken behavior.
>
> Symptom: In Zope 2.8.1 it is *impossible* to override a
> ClassSecurityInfo security declaration in an Archetypes-derived content
> item. (I have a small set of unit tests that proves the behavior under
> Zope 2.8.1 if anyone is interested)
>
> A little background: When you register an Archetypes-derived content
> type, it will do all the generated accessor/setter method magic and
> then call InitializeClass a second time.
>
> The code in lib/python/App/class_init.py has changed between Zope 2.7.x
> and Zope 2.8 in order to support new-style classes. To be more precise,
> instead of manipulating the class __dict__ directly we now use
> setattr/delattr/etc. This change seems to have "un-broken" code which
> did not do what the code comments suggest. Namely, when a class is sent
> through class_init.default_class_init__ (better known as
> Globals.InitializeClass) the class __dict__ is searched to find objects
> that look like ClassSecurityInfo instances in order to read and apply
> the security settings. After finding the ClassSecurityInfo instance, it
> is force-deleted from the object (the comments say, "out of paranoia").
> However, somehow this did not work correctly in Zope 2.7.x, where the
> deletion call looked like...
>
> del dict[key]
>
> (dict being the class __dict__, and key being the name of the
> ClassSecurityInfo instance). Under Zope 2.8, it looks like this:
>
> delattr(self, key)
>
> (self being the class object).
>
> Under Zope 2.7, the security object *would still be there* when hitting
> InitializeClass for the second time via Archetypes' registerType, which
> in turn meant Archetypes would not instantiate its own
> ClassSecurityInfo instance and stuff it with the declarations from
> whatever Archetypes-derived base class you used.
>
> In Zope 2.8, the deletion actually works as intended - but due to that
> fact Archetypes will instantiate its own ClassSecurityInfo and populate
> it with the declarations from the base class that I am trying to
> override. So the overridden settings are all overwritten again by the
> base class declaration.
>
> My question is, what is the reasoning behind deleting the
> ClassSecurityInfo object from the class after it has been read the
> first time? How can this be implemented in a sane way so that custom
> security declarations can be retained?
My understanding (and the way we use it when monkey patching for instance)
is that whenevery you apply new security to a class, you create a new
ClassSecurityInfo on it. It only defines "new stuff" to do. The real
synthesized security is still stored in __ac_permissions__.
class C(SimpleItem):
security = ClassSecurityInfo()
security.declareProtected(...)
def foo(): ...
InitializeClass(C)
then later on:
security = ClassSecurityInfo()
C.security = security
security.declareProtected(...)
C.newmethod = something
InitializeClass(C)
Anyway that's what I do. I never relied on a preexisting C.security.
Florent
--
Florent Guillaume, Nuxeo (Paris, France) CTO, Director of R&D
+33 1 40 33 71 59 http://nuxeo.com fg at nuxeo.com
More information about the Zope-Dev
mailing list