[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