Commit 1502dc3c authored by Hanno Schlichting's avatar Hanno Schlichting

LP #1047318: Tighten import restrictions for restricted code.

parent a3639de7
......@@ -5,9 +5,11 @@ This file contains change information for the current Zope release.
Change information for previous versions of Zope can be found at
http://docs.zope.org/zope2/releases/.
2.12.24 (unreleased)
2.12.24 (2012-09-09)
--------------------
- LP #1047318: Tighten import restrictions for restricted code.
- Fix a bug in ZopeSecurityPolicy.py. Global variable `rolesForPermissionOn`
could be overridden if `__role__` had custom rolesForPermissionOn.
......
......@@ -16,7 +16,7 @@ import os
from setuptools import setup, find_packages, Extension
setup(name='Zope2',
version='2.12.24dev',
version='2.12.24',
url='http://www.zope.org',
license='ZPL 2.1',
description='Zope2 application server / web framework',
......
......@@ -211,7 +211,9 @@ _appliedModuleSecurity = {}
def secureModule(mname, *imp):
modsec = _moduleSecurity.get(mname, None)
if modsec is None:
return
if mname in _appliedModuleSecurity:
return sys.modules[mname]
return # no MSI, no module
if imp:
__import__(mname, *imp)
......
......@@ -310,7 +310,7 @@ class GuardedListType:
return list.sorted(iterable, cmp=None, key=None, reverse=False)
safe_builtins['list'] = GuardedListType()
class GuardedDictType:
def __call__(self, *args, **kwargs):
return dict(*args, **kwargs)
......@@ -329,20 +329,16 @@ def guarded_sum(sequence, start=0):
safe_builtins['sum'] = guarded_sum
def load_module(module, mname, mnameparts, validate, globals, locals):
modules = sys.modules
while mnameparts:
nextname = mnameparts.pop(0)
if mname is None:
mname = nextname
else:
mname = '%s.%s' % (mname, nextname)
nextmodule = modules.get(mname, None)
if nextmodule is None:
nextmodule = secureModule(mname, globals, locals)
if nextmodule is None:
return
else:
secureModule(mname)
# import (if not already imported) and check for MSI
nextmodule = secureModule(mname, globals, locals)
if nextmodule is None: # not allowed
return
if module and not validate(module, module, nextname, nextmodule):
return
module = nextmodule
......@@ -440,7 +436,7 @@ def __imul__(x, y):
def __idiv__(x, y):
x /= y
return x
def __ifloordiv__(x, y):
x //= y
return x
......
......@@ -26,11 +26,18 @@ from AccessControl.SecurityInfo import secureModule
from AccessControl.SecurityInfo import allow_module
from AccessControl.SecurityInfo import allow_class
from AccessControl.SimpleObjectPolicies import allow_type
from AccessControl.unauthorized import Unauthorized # XXX
from AccessControl.unauthorized import Unauthorized
from AccessControl.ZopeGuards import full_write_guard
from AccessControl.ZopeGuards import safe_builtins
ModuleSecurityInfo('AccessControl').declarePublic('getSecurityManager')
# allow imports of utility_builtins
for name in ('string', 'math', 'random', 'sets'):
ModuleSecurityInfo(name).setDefaultAccess('allow')
ModuleSecurityInfo('DateTime').declarePublic('DateTime')
from AccessControl import DTML # XXX side effects?
del DTML
......@@ -42,6 +42,9 @@ class ModuleSecurityTests(unittest.TestCase):
from AccessControl.ZopeGuards import guarded_import
guarded_import(module, fromlist=fromlist, level=level)
def test_unprotected_module(self):
self.assertUnauth('os', ())
def testPrivateModule(self):
self.assertUnauth('AccessControl.tests.private_module', ())
self.assertUnauth('AccessControl.tests.private_module', ('priv',))
......
......@@ -761,10 +761,6 @@ print foo(**kw)
g['__name__'] = __name__ # so classes can be defined in the script
return code, g
def testPythonRealAC(self):
code, its_globals = self._compile("actual_python.py")
exec code in its_globals
# Compile code in fname, as restricted Python. Return the
# compiled code, and a safe globals dict for running it in.
# fname is the string name of a Python file; it must be found
......
......@@ -40,7 +40,7 @@ from DocumentTemplate.DT_Var import url_unquote_plus
from DocumentTemplate.DT_Var import restructured_text
from ZPublisher.HTTPRequest import record
security = ModuleSecurityInfo()
security = ModuleSecurityInfo('Products.PythonScripts.standard')
security.declarePublic('special_formats',
'whole_dollars',
......
......@@ -131,9 +131,6 @@ class TestPythonScriptNoAq(PythonScriptTestBase):
def testCollector2295(self):
res = self._newPS('if False:\n pass\n#hi')
def testCollector2295(self):
res = self._newPS('if False:\n pass\n#hi')
def testReduce(self):
res = self._newPS('return reduce(lambda x, y: x + y, [1,3,5,7])')()
self.assertEqual(res, 16)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment