[Checkins] SVN: Zope/branches/2.12/ Fix regression in treatment of trusted code in view page templates.

Martin Aspeli optilude at gmx.net
Sun Dec 13 04:28:24 EST 2009


Log message for revision 106436:
  Fix regression in treatment of trusted code in view page templates.

Changed:
  U   Zope/branches/2.12/doc/CHANGES.rst
  U   Zope/branches/2.12/src/Products/Five/browser/tests/test_pagetemplatefile.py
  U   Zope/branches/2.12/src/Products/PageTemplates/Expressions.py

-=-
Modified: Zope/branches/2.12/doc/CHANGES.rst
===================================================================
--- Zope/branches/2.12/doc/CHANGES.rst	2009-12-12 10:58:43 UTC (rev 106435)
+++ Zope/branches/2.12/doc/CHANGES.rst	2009-12-13 09:28:23 UTC (rev 106436)
@@ -27,6 +27,12 @@
 Bugs Fixed
 ++++++++++
 
+- Fixed a regression in Products.PageTemplates that meant filesystem templates
+  using Products.Five.browser.pagetemplatefile would treat TALES path
+  expressions (but not python expressions) as protected code and so attempt
+  to apply security. See original issue here:
+  http://codespeak.net/pipermail/z3-five/2007q2/002185.html
+
 - LP #491249:  fix tabindex on ZRDB connection test form.
 
 - LP #490514:  preserve tainting when calling into DTML from ZPT.

Modified: Zope/branches/2.12/src/Products/Five/browser/tests/test_pagetemplatefile.py
===================================================================
--- Zope/branches/2.12/src/Products/Five/browser/tests/test_pagetemplatefile.py	2009-12-12 10:58:43 UTC (rev 106435)
+++ Zope/branches/2.12/src/Products/Five/browser/tests/test_pagetemplatefile.py	2009-12-13 09:28:23 UTC (rev 106436)
@@ -42,15 +42,15 @@
         from zope.tales.pythonexpr import PythonExpr
         from zope.contentprovider.tales import TALESProviderExpression
         from Products.PageTemplates.DeferExpr import LazyExpr
-        from Products.PageTemplates.Expressions import ZopePathExpr
+        from Products.PageTemplates.Expressions import TrustedZopePathExpr
         from Products.PageTemplates.Expressions import SecureModuleImporter
 
         vptf = self._makeOne('seagull.pt')
         engine = vptf.pt_getEngine()
-        self.assertEqual(engine.types['standard'], ZopePathExpr)
-        self.assertEqual(engine.types['path'], ZopePathExpr)
-        self.assertEqual(engine.types['exists'], ZopePathExpr)
-        self.assertEqual(engine.types['nocall'], ZopePathExpr)
+        self.assertEqual(engine.types['standard'], TrustedZopePathExpr)
+        self.assertEqual(engine.types['path'], TrustedZopePathExpr)
+        self.assertEqual(engine.types['exists'], TrustedZopePathExpr)
+        self.assertEqual(engine.types['nocall'], TrustedZopePathExpr)
         self.assertEqual(engine.types['string'], StringExpr)
         self.assertEqual(engine.types['python'], PythonExpr)
         self.assertEqual(engine.types['not'], NotExpr)

Modified: Zope/branches/2.12/src/Products/PageTemplates/Expressions.py
===================================================================
--- Zope/branches/2.12/src/Products/PageTemplates/Expressions.py	2009-12-12 10:58:43 UTC (rev 106435)
+++ Zope/branches/2.12/src/Products/PageTemplates/Expressions.py	2009-12-13 09:28:23 UTC (rev 106436)
@@ -79,6 +79,26 @@
                                          request=request)
     return object
 
+def trustedBoboAwareZopeTraverse(object, path_items, econtext):
+    """Traverses a sequence of names, first trying attributes then items.
+
+    This uses Zope 3 path traversal where possible and interacts
+    correctly with objects providing OFS.interface.ITraversable when
+    necessary (bobo-awareness).
+    """
+    request = getattr(econtext, 'request', None)
+    path_items = list(path_items)
+    path_items.reverse()
+
+    while path_items:
+        name = path_items.pop()
+        if OFS.interfaces.ITraversable.providedBy(object):
+            object = object.unrestrictedTraverse(name)
+        else:
+            object = traversePathElement(object, name, path_items,
+                                         request=request)
+    return object
+
 def render(ob, ns):
     """Calls the object, possibly a document template, or just returns
     it if not callable.  (From DT_Util.py)
@@ -104,11 +124,13 @@
 
 class ZopePathExpr(PathExpr):
 
+    _TRAVERSER = staticmethod(boboAwareZopeTraverse)
+
     def __init__(self, name, expr, engine):
         if not expr.strip():
             expr = 'nothing'
         super(ZopePathExpr, self).__init__(name, expr, engine,
-                                           boboAwareZopeTraverse)
+                                           self._TRAVERSER)
 
     # override this to support different call metrics (see bottom of
     # method) and Zope 2's traversal exceptions (ZopeUndefs instead of
@@ -146,6 +168,9 @@
                 return 1
         return 0
 
+class TrustedZopePathExpr(ZopePathExpr):
+    _TRAVERSER = staticmethod(trustedBoboAwareZopeTraverse)
+
 class SafeMapping(MultiMapping):
     """Mapping with security declarations and limited method exposure.
 
@@ -347,11 +372,11 @@
             return False
         return ob1 == ob2
 
-def createZopeEngine():
+def createZopeEngine(zpe=ZopePathExpr):
     e = ZopeEngine()
     e.iteratorFactory = PathIterator
-    for pt in ZopePathExpr._default_type_names:
-        e.registerType(pt, ZopePathExpr)
+    for pt in zpe._default_type_names:
+        e.registerType(pt, zpe)
     e.registerType('string', StringExpr)
     e.registerType('python', ZRPythonExpr.PythonExpr)
     e.registerType('not', NotExpr)
@@ -364,7 +389,7 @@
 def createTrustedZopeEngine():
     # same as createZopeEngine, but use non-restricted Python
     # expression evaluator
-    e = createZopeEngine()
+    e = createZopeEngine(TrustedZopePathExpr)
     e.types['python'] = PythonExpr
     return e
 



More information about the checkins mailing list