[Zope3-checkins] SVN: Zope3/branches/ZopeX3-3.0/src/zope/ Merged from trunk

Jim Fulton jim at zope.com
Wed Jul 28 15:59:49 EDT 2004


Log message for revision 26823:
  Merged from trunk
  
    r26819 | jim | 2004-07-28 15:37:35 -0400 (Wed, 28 Jul 2004) | 36 lines
  
  
    Refactored untrusted-python support:
  
    - collecting restricted builtins, restricted compilation, and
      the slightly higher level "interpreter" support in a single
      untrustedpython package.
  
    - Changed the way restricted builtins are handled so that we create an
      immutable module, rather than a dictionary.  This is to make
      __builtin__ immutable, to prevent evil code from changing it.
  
    - We now use Fred's restricted compiler rather than the basic Python
      compiler so that we can manipulate code to:
  
      - Make sure that the results of getattrs are proxied
  
      - Prevent use of exec, which we don't have code to handle yet.
        (Not sure if we'll bother.)
  
      - prevent use of raise or try/except, which we don't support yet,
        but will eventually.
  
      - Make sure that prints go to an interpreter-supplied object, rather
        than sys.stdout.
  
    - Updated varous clients to reflect new locations and APIs.
  
    - Had to work around some bugs in the Python compiler modules.
      Mote that global statements aren't handled correctly.
  
    I did this because the restricted interpreter was to be included in
    the X3.0 release and, even though it's not actually used, I was afraid
    that someone would try to use it.  Now, we've at least made an effort
    to get it right, although a more thorough review is needed.
  


Changed:
  U   Zope3/branches/ZopeX3-3.0/src/zope/app/DEPENDENCIES.cfg
  U   Zope3/branches/ZopeX3-3.0/src/zope/app/pagetemplate/engine.py
  D   Zope3/branches/ZopeX3-3.0/src/zope/restrictedpython/
  D   Zope3/branches/ZopeX3-3.0/src/zope/security/builtins.py
  D   Zope3/branches/ZopeX3-3.0/src/zope/security/interpreter.py
  D   Zope3/branches/ZopeX3-3.0/src/zope/security/tests/test_builtins.py
  D   Zope3/branches/ZopeX3-3.0/src/zope/security/tests/test_interpreter.py
  A   Zope3/branches/ZopeX3-3.0/src/zope/security/untrustedpython/
  _U  Zope3/branches/ZopeX3-3.0/src/zope/security/untrustedpython/__init__.py
  _U  Zope3/branches/ZopeX3-3.0/src/zope/security/untrustedpython/builtins.py
  _U  Zope3/branches/ZopeX3-3.0/src/zope/security/untrustedpython/builtins.txt
  _U  Zope3/branches/ZopeX3-3.0/src/zope/security/untrustedpython/interpreter.py
  _U  Zope3/branches/ZopeX3-3.0/src/zope/security/untrustedpython/interpreter.txt
  _U  Zope3/branches/ZopeX3-3.0/src/zope/security/untrustedpython/rcompile.py
  _U  Zope3/branches/ZopeX3-3.0/src/zope/security/untrustedpython/rcompile.txt
  _U  Zope3/branches/ZopeX3-3.0/src/zope/security/untrustedpython/tests.py
  U   Zope3/branches/ZopeX3-3.0/src/zope/tales/pythonexpr.py


-=-
Modified: Zope3/branches/ZopeX3-3.0/src/zope/app/DEPENDENCIES.cfg
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/app/DEPENDENCIES.cfg	2004-07-28 19:50:04 UTC (rev 26822)
+++ Zope3/branches/ZopeX3-3.0/src/zope/app/DEPENDENCIES.cfg	2004-07-28 19:59:49 UTC (rev 26823)
@@ -17,7 +17,6 @@
 zope.pagetemplate
 zope.proxy
 zope.publisher
-zope.restrictedpython
 zope.schema
 zope.security
 zope.server

Modified: Zope3/branches/ZopeX3-3.0/src/zope/app/pagetemplate/engine.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/app/pagetemplate/engine.py	2004-07-28 19:50:04 UTC (rev 26822)
+++ Zope3/branches/ZopeX3-3.0/src/zope/app/pagetemplate/engine.py	2004-07-28 19:59:49 UTC (rev 26823)
@@ -29,9 +29,9 @@
 from zope.component.exceptions import ComponentLookupError
 from zope.exceptions import NotFoundError
 from zope.proxy import removeAllProxies
-from zope.restrictedpython import rcompile
+from zope.security.untrustedpython import rcompile
 from zope.security.proxy import ProxyFactory
-from zope.security.builtins import RestrictedBuiltins
+from zope.security.untrustedpython.builtins import SafeBuiltins
 from zope.i18n import translate
 
 from zope.app import zapi
@@ -81,23 +81,12 @@
 # version of getattr() that wraps values in security proxies where
 # appropriate:
 
-_marker = object()
 
-def safe_getattr(object, name, default=_marker):
-    if default is _marker:
-        return ProxyFactory(getattr(object, name))
-    else:
-        return ProxyFactory(getattr(object, name, default))
-
-RestrictedBuiltins = RestrictedBuiltins.copy()
-RestrictedBuiltins["getattr"] = safe_getattr
-
-
 class ZopePythonExpr(PythonExpr):
 
     def __call__(self, econtext):
         __traceback_info__ = self.text
-        vars = self._bind_used_names(econtext, RestrictedBuiltins)
+        vars = self._bind_used_names(econtext, SafeBuiltins)
         return eval(self._code, vars)
 
     def _compile(self, text, filename):

Deleted: Zope3/branches/ZopeX3-3.0/src/zope/security/builtins.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/security/builtins.py	2004-07-28 19:50:04 UTC (rev 26822)
+++ Zope3/branches/ZopeX3-3.0/src/zope/security/builtins.py	2004-07-28 19:59:49 UTC (rev 26823)
@@ -1,103 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE
-#
-##############################################################################
-"""Protection of builtin objects.
-
-$Id$
-"""
-import sys
-
-def RestrictedBuiltins():
-
-    from zope.security.proxy import ProxyFactory
-    from zope.security.checker import NamesChecker
-
-    # It's better to say what is safe than it say what is not safe
-    _safe = [
-        'ArithmeticError', 'AssertionError', 'AttributeError',
-        'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError',
-        'Exception', 'FloatingPointError', 'IOError', 'ImportError',
-        'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt',
-        'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented',
-        'NotImplementedError', 'OSError', 'OverflowError', 'OverflowWarning',
-        'ReferenceError', 'RuntimeError', 'RuntimeWarning', 'StandardError',
-        'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError',
-        'SystemExit', 'TabError', 'TypeError', 'UnboundLocalError',
-        'UnicodeError', 'UserWarning', 'ValueError', 'Warning',
-        'ZeroDivisionError',
-        '__debug__', '__doc__', '__name__', 'abs', 'apply', 'bool',
-        'buffer', 'callable', 'chr', 'classmethod', 'cmp', 'coerce',
-        'complex', 'copyright', 'credits', 'delattr',
-        'dict', 'divmod', 'filter', 'float', 'getattr',
-        'hasattr', 'hash', 'hex', 'id', 'int', 'isinstance',
-        'issubclass', 'iter', 'len', 'license', 'list',
-        'long', 'map', 'max', 'min', 'object', 'oct', 'ord', 'pow',
-        'property', 'quit', 'range', 'reduce', 'repr', 'round',
-        'setattr', 'slice', 'staticmethod', 'str', 'super', 'tuple',
-        'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip',
-        'True', 'False'
-        ]
-
-    # XXX dir segfaults with a seg fault due to a bas tuple check in
-    # merge_class_dict in object.c. The assert macro seems to be doing
-    # the wrong think. Basically, if an object has bases, then bases
-    # is assumed to be a tuple.
-
-    # Anything that accesses an external file is a no no:
-    # 'open', 'execfile', 'file'
-
-    # We dont want restricted code to call exit: 'SystemExit', 'exit'
-
-    # Other no nos:
-    #    help prints
-    #    input does I/O
-    #    raw_input does I/O
-    #    intern's effect is too global
-    #    reload does import, XXX doesn't it use __import__?
-
-    _builtinTypeChecker = NamesChecker(
-        ['__str__', '__repr__', '__name__', '__module__',
-         '__bases__', '__call__'])
-
-    import __builtin__
-
-    builtins = {}
-    for name in _safe:
-        value = getattr(__builtin__, name)
-        if isinstance(value, type):
-            value = ProxyFactory(value, _builtinTypeChecker)
-        else:
-            value = ProxyFactory(value)
-        builtins[name] = value
-
-    def __import__(name, globals=None, locals=None, fromlist=()):
-        # Waaa, we have to emulate __import__'s weird semantics.
-        try:
-            module = sys.modules[name]
-            if fromlist:
-                return module
-
-            l = name.find('.')
-            if l < 0:
-                return module
-
-            return sys.modules[name[:l]]
-
-        except KeyError:
-            raise ImportError(name)
-
-    builtins['__import__'] = ProxyFactory(__import__)
-
-    return builtins
-
-RestrictedBuiltins = RestrictedBuiltins()

Deleted: Zope3/branches/ZopeX3-3.0/src/zope/security/interpreter.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/security/interpreter.py	2004-07-28 19:50:04 UTC (rev 26822)
+++ Zope3/branches/ZopeX3-3.0/src/zope/security/interpreter.py	2004-07-28 19:59:49 UTC (rev 26823)
@@ -1,38 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE
-#
-##############################################################################
-"""Restricted interpreter.
-
-XXX This code is not used!  Before using it, a serious security review
-should be undertaken.
-
-XXX (SR) Yes the code is used for the inline Python support. As far as I can
-tell the security works well, as I had to make all sorts of security
-declarations to make it work. 
-
-$Id$
-"""
-from zope.security.builtins import RestrictedBuiltins
-
-class RestrictedInterpreter:
-
-    def __init__(self):
-        self.globals = {}
-        self.locals = {}
-
-    def ri_exec(self, code):
-        """Execute Python code in a restricted environment.
-
-        The value of code can be either source or binary code."""
-        self.globals['__builtins__'] = RestrictedBuiltins
-        exec code in self.globals, self.locals

Deleted: Zope3/branches/ZopeX3-3.0/src/zope/security/tests/test_builtins.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/security/tests/test_builtins.py	2004-07-28 19:50:04 UTC (rev 26822)
+++ Zope3/branches/ZopeX3-3.0/src/zope/security/tests/test_builtins.py	2004-07-28 19:59:49 UTC (rev 26823)
@@ -1,44 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE
-#
-##############################################################################
-"""Restricted Builtins Tests
-
-$Id$
-"""
-
-from unittest import makeSuite, TestCase, main
-from zope.testing.cleanup import CleanUp # Base class w registry cleanup
-
-class Test(CleanUp, TestCase):
-
-    def test(self):
-        from zope.security.builtins import RestrictedBuiltins
-        from zope.security.interfaces import Forbidden
-
-        def e(expr):
-            return eval(expr, {'__builtins__': RestrictedBuiltins})
-
-        self.assertEqual(e('__import__("sys").__name__'), "sys")
-        self.assertEqual(e('__import__("zope.security").__name__'), "zope")
-        self.assertEqual(e(
-            '__import__("zope.security", {}, None, ["__doc__"]).__name__'),
-                         "zope.security")
-        self.assertRaises(Forbidden, e, '__import__("sys").exit')
-
-
-
-def test_suite():
-    return makeSuite(Test)
-
-if __name__=='__main__':
-    main(defaultTest='test_suite')

Deleted: Zope3/branches/ZopeX3-3.0/src/zope/security/tests/test_interpreter.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/security/tests/test_interpreter.py	2004-07-28 19:50:04 UTC (rev 26822)
+++ Zope3/branches/ZopeX3-3.0/src/zope/security/tests/test_interpreter.py	2004-07-28 19:59:49 UTC (rev 26823)
@@ -1,74 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2003 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-import unittest
-
-from zope.security.interpreter import RestrictedInterpreter
-from zope.security.checker import defineChecker
-
-from zope.testing.cleanup import CleanUp
-
-class RITests(unittest.TestCase, CleanUp):
-
-    def setUp(self):
-        CleanUp.setUp(self)
-        self.rinterp = RestrictedInterpreter()
-
-    def tearDown(self):
-        CleanUp.tearDown(self)
-
-    def testExec(self):
-        self.rinterp.ri_exec("str(type(1))\n")
-
-    def testImport(self):
-        self.rinterp.ri_exec("import zope.security.proxy")
-
-    def testWrapping(self):
-        # make sure we've really got proxies
-        import types
-        from zope.security.checker import NamesChecker
-
-        checker = NamesChecker(['Proxy'])
-
-        import zope.security.proxy
-        defineChecker(zope.security.proxy, checker)
-
-        checker = NamesChecker(['BuiltinFunctionType'])
-        defineChecker(types, checker)
-
-        code = ("from zope.security.proxy import Proxy\n"
-                "import types\n"
-                "assert type(id) is not types.BuiltinFunctionType\n"
-                )
-        self.rinterp.ri_exec(code)
-
-    def testGlobalVersusLocal(self):
-        code = ("global x\n"
-                "x = 1\n"
-                "y = 2\n")
-        self.rinterp.ri_exec(code)
-        self.assert_('x' in self.rinterp.globals)
-        self.assert_('y' not in self.rinterp.globals)
-        self.assertEqual(self.rinterp.globals['x'], 1)
-        self.assert_('x' not in self.rinterp.locals)
-        self.assert_('y' in self.rinterp.locals)
-        self.assertEqual(self.rinterp.locals['y'], 2)
-
-
-def test_suite():
-    return unittest.makeSuite(RITests)
-
-
-if __name__=='__main__':
-    from unittest import main
-    main(defaultTest='test_suite')

Copied: Zope3/branches/ZopeX3-3.0/src/zope/security/untrustedpython (from rev 26819, Zope3/trunk/src/zope/security/untrustedpython)

Modified: Zope3/branches/ZopeX3-3.0/src/zope/tales/pythonexpr.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/tales/pythonexpr.py	2004-07-28 19:50:04 UTC (rev 26822)
+++ Zope3/branches/ZopeX3-3.0/src/zope/tales/pythonexpr.py	2004-07-28 19:59:49 UTC (rev 26823)
@@ -18,7 +18,8 @@
 
 class PythonExpr:
     def __init__(self, name, expr, engine):
-        text = ' '.join(expr.splitlines()).strip()
+        text = '\n'.join(expr.splitlines()) # normalize line endings
+        text = '(' + text + ')' # Put text in parens so newlines don't matter
         self.text = text
         try:
             code = self._compile(text, '<string>')
@@ -35,6 +36,8 @@
         names = {}
         vars = econtext.vars
         marker = self
+        if not isinstance(builtins, dict):
+            builtins = builtins.__dict__
         for vname in self._varnames:
             val = vars.get(vname, marker)
             if val is not marker:



More information about the Zope3-Checkins mailing list