[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