2.7.0-b2 - Critical ZPT TAL bug when using content-type text/xml
Yesterday I discovered a bug in ZPT for which I'm having trouble tracking down the source. This bug does not appear to occur in 2.6, but does appear to occur in both 2.7.0-b2 and 2.7.0-b1. Basically, if you're using a ZPT with a content-type text/xml, using a TAL path expression to access an attribute or method causes a security violation (Unauthorized). It does not happen if the ZPT is using content-type text/html. This is a critical bug for us, it will affect dozens if not hundreds of XML producing ZPT's if we were to upgrade to 2.7 from 2.6. I notice that someone previously reported something like this on the Zope list but I couldn't find a resolution (the message was a couple of months back), and there is a bug in the collector: http://collector.zope.org/Zope/1034/ To which I have added a comment, a test case and a traceback. The bug was talking about METAL macros, but it is almost certainly related. Two things are known to workaround this bug: 1) ZOPE_SECURITY_POLICY=PYTHON would probably work, since I forced an import error in AccessControl/ZopeGuards.py to force the use of the python version of guarded_getattr, and that fixed the problem. Which might suggest the problem is in cAccessControl ... though I dropped in the 2.6 version of that, and it didn't seem to fix the problem (maybe something in cAccessControl is only trigged under this scenerio), 2) Using getattr rather than guarded_getattr in PageTemplates/Expressions.py, line 348. Not the best solution :) The test case, for those too lazy to look in the collector (:)): --- 1. Create a page template 2. Use the text: <test xmlns:tal="http://xml.zope.org/namespaces/tal" tal:replace="here/id"/> 3. Set to content-type text/html -- it should work when you test it. 4. Set to content-type text/xml -- you will get a security violation when you test it (Unauthorized: You are not allowed to access 'id' in this context). ----- Any help tracking down this problem would be very greatly appreciated. Many thanks, Richard Waid Network/Software Engineer http://iopen.net
Richard Waid wrote:
Basically, if you're using a ZPT with a content-type text/xml, using a TAL path expression to access an attribute or method causes a security violation (Unauthorized). It does not happen if the ZPT is using content-type text/html.
Ah, guarded_getattr is doing something wrong with Unicode attribute names, though I'm not sure exactly what.
Thanks for the pointer -- I've updated the bug. Cheers, Evan @ 4-am
Until cAccessControl.c is fixed, you can work around the problem with a simple patch to Products/PageTemplates/Expressions.py, in restrictedTraverse(): if isinstance(name, TupleType): object = object(*name) continue + + name = str(name) if not name or name[0] == '_': # Skip directly to item access Cheers, Evan @ 4-am
Evan Simpson wrote:
Until cAccessControl.c is fixed, you can work around the problem with a simple patch to Products/PageTemplates/Expressions.py, in restrictedTraverse():
if isinstance(name, TupleType): object = object(*name) continue + + name = str(name) if not name or name[0] == '_': # Skip directly to item access
Thanks Evan (definitely a better idea that turning off guarded_getattr anyway :)). Any hunches why it doesn't happen in 2.6.x? (maybe the xml didn't get converted to unicode?) I'd imagine that it's probably quite a pervasive bug -- comparing two strings is obviously quite a common situation ... just turned up by this particular situation. Just a quick grep turns up 50 instances of PyString_Check in the 2.7.0-b2 source, and 4 instances of PyUnicode_Check. cDocumentTemplate.c and UnicodeSplitter.c (no suprises there) seem to do the right thing. Pretty much every other c file needs to be checked. In particular cPersistence.c, cPickleCache.c, Acquisition.c, ComputedAttribute.c, ExtensionClass.c and cAccessControl.c all use PyString_Check, and they'd obviously be bad places for things to go wrong :) Best regards, Richard Waid Network/Software Engineer http://iopen.net
participants (2)
-
Evan Simpson -
Richard Waid