CVE-2021-32807 (published 2021-07-30T22:15Z)

The module `AccessControl` defines security policies for Python code used in restricted code within Zope applications. Restricted code is any code that resides in Zope\'s object database, such as the contents of `Script (Python)` objects. The policies defined in `AccessControl` severely restrict access to Python modules and only exempt a few that are deemed safe, such as Python\'s `string` module. However, full access to the `string` module also allows access to the class `Formatter`, which can be overridden and extended within `Script (Python)` in a way that provides access to other unsafe Python libraries. Those unsafe Python libraries can be used for remote code execution. By default, you need to have the admin-level Zope "Manager" role to add or edit `Script (Python)` objects through the web. Only sites that allow untrusted users to add/edit these scripts through the web - which would be a very unusual configuration to begin with - are at risk. The problem has been fixed in AccessControl 4.3 and 5.2. Only AccessControl versions 4 and 5 are vulnerable, and only on Python 3, not Python 2.7. As a workaround, a site administrator can restrict adding/editing `Script (Python)` objects through the web using the standard Zope user/role permission mechanisms. Untrusted users should not be assigned the Zope Manager role and adding/editing these scripts through the web should be restricted to trusted users only. This is the default configuration in Zope.

Severity: MEDIUM
CVSS v2 base score: 6.5 (AV:N/AC:L/Au:S/C:P/I:P/A:P)
CVSS v3 base score: 7.2, HIGH (CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-1321
cwe_name: Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution')
description: The product receives input from an upstream component that specifies attributes that are to be initialized or updated in an object, but it does not properly control modifications of attributes of the object prototype.
extended_description: 
				By adding or modifying attributes of an object prototype, it is possible to create attributes that exist on every object, or replace critical attributes with malicious ones. This can be problematic if the product depends on existence or non-existence of certain attributes, or uses pre-defined attributes of object prototype (such as hasOwnProperty, toString or valueOf).
				This weakness is usually exploited by using a special attribute of objects called proto,  constructor or prototype. Such attributes give access to the object prototype. This weakness is often found in code that assigns object attributes based on user input, or merges or clones objects recursively.
			
			

Fix information:
repo_url: https://github.com/zopefoundation/AccessControl
commit_details: repo_url: https://github.com/zopefoundation/AccessControl
author: Jens Vagelpohl
author_date: 2021-07-30 09:25:07+02:00
msg: Merge pull request from GHSA-qcx9-j53g-ccgf
repository: repo_url: https://github.com/zopefoundation/AccessControl
repo_name: zopefoundation/AccessControl
description: Security framework for Zope.
repo_language: Python
owner: zopefoundation
file_changes: filename: CHANGES.rst
change_type: ModificationType.MODIFY
diff: @@ -6,7 +6,8 @@ For changes before version 3.0, see ``HISTORY.rst``.
 5.1 (unreleased)
 ----------------
 
-- Nothing changed yet.
+- Fix a remote code execution issue by preventing access to
+  ``string.Formatter`` from restricted code.
 
 
 5.0 (2020-10-07)

programming_language: Markdown
filename: ZopeGuards.py
change_type: ModificationType.MODIFY
diff: @@ -30,6 +30,7 @@ from RestrictedPython.Guards import safe_builtins
 from RestrictedPython.Utilities import utility_builtins
 from zExceptions import Unauthorized
 
+from AccessControl.SecurityInfo import ModuleSecurityInfo
 from AccessControl.SecurityInfo import secureModule
 from AccessControl.SecurityManagement import getSecurityManager
 from AccessControl.SimpleObjectPolicies import ContainerAssertions
@@ -57,6 +58,13 @@ string.__allow_access_to_unprotected_subobjects__ = 1
 math.__allow_access_to_unprotected_subobjects__ = 1
 random.__allow_access_to_unprotected_subobjects__ = 1
 
+# Mark some unprotected module attributes as private, these should not be
+# used in untrusted Python code such as Scripts (Python)
+string_modsec = ModuleSecurityInfo('string')
+for name in ('Formatter', 'Template'):
+    string_modsec.declarePrivate(name)  # NOQA: D001
+secureModule('string')
+
 # AccessControl.Implementation inserts these names into this module as
 # module globals:  aq_validate, guarded_getattr
 

programming_language: Python
filename: testZopeSecurityPolicy.py
change_type: ModificationType.MODIFY
diff: @@ -278,6 +278,19 @@ class ZopeSecurityPolicyTestBase(unittest.TestCase):
         c.attr = PublicMethod()
         self.assertPolicyAllows(c, 'attr')
 
+    def testAccessToStringModule(self):
+        # The string module is available to restricted code and its members are
+        # explicitly allowed via a
+        # ``__allow_access_to_unprotected_subobjects__`` declaration. However,
+        # a few classes are exempted and declared private, they can indirectly
+        # provide uncontrolled access to system libraries from within
+        # restricted code.
+        import string
+
+        self.assertPolicyAllows(string, 'printable')
+        self.assertPolicyDenies(string, 'Formatter')
+        self.assertPolicyDenies(string, 'Template')
+
     def testUnicodeAttributeLookups(self):
         item = self.item
         r_item = self.a.r_item

programming_language: Python