Skip to content

Commit

Permalink
LP #1047318: Tighten import restrictions for restricted code.
Browse files Browse the repository at this point in the history
  • Loading branch information
hannosch committed Sep 9, 2012
1 parent a3639de commit 1502dc3
Show file tree
Hide file tree
Showing 9 changed files with 25 additions and 22 deletions.
4 changes: 3 additions & 1 deletion doc/CHANGES.rst
Expand Up @@ -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.

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Expand Up @@ -16,7 +16,7 @@
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',
Expand Down
4 changes: 3 additions & 1 deletion src/AccessControl/SecurityInfo.py
Expand Up @@ -211,7 +211,9 @@ class ClassSecurityInformation(ClassSecurityInfo):
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)
Expand Down
16 changes: 6 additions & 10 deletions src/AccessControl/ZopeGuards.py
Expand Up @@ -310,7 +310,7 @@ def sorted(self, iterable, cmp=None, key=None, reverse=False):
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)
Expand All @@ -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
Expand Down Expand Up @@ -440,7 +436,7 @@ def __imul__(x, y):
def __idiv__(x, y):
x /= y
return x

def __ifloordiv__(x, y):
x //= y
return x
Expand Down
9 changes: 8 additions & 1 deletion src/AccessControl/__init__.py
Expand Up @@ -26,11 +26,18 @@
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
3 changes: 3 additions & 0 deletions src/AccessControl/tests/testModuleSecurity.py
Expand Up @@ -42,6 +42,9 @@ def assertAuth(self, module, fromlist, level=-1):
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',))
Expand Down
4 changes: 0 additions & 4 deletions src/AccessControl/tests/testZopeGuards.py
Expand Up @@ -761,10 +761,6 @@ def _compile_str(self, text, name):
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
Expand Down
2 changes: 1 addition & 1 deletion src/Products/PythonScripts/standard.py
Expand Up @@ -40,7 +40,7 @@
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',
Expand Down
3 changes: 0 additions & 3 deletions src/Products/PythonScripts/tests/testPythonScript.py
Expand Up @@ -131,9 +131,6 @@ def testArithmetic(self):
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)
Expand Down

0 comments on commit 1502dc3

Please sign in to comment.