CVE-2023-41039 (Python)

RestrictedPython is a restricted execution environment for Python to run untrusted code. Python's "format" functionality allows someone controlling the format string to "read" all objects accessible through recursive attribute lookup and subscription from objects he can access. This can lead to critical information disclosure. With `RestrictedPython`, the format functionality is available via the `format` and `format_map` methods of `str` (and `unicode`) (accessed either via the class or its instances) and via `string.Formatter`. All known versions of `RestrictedPython` are vulnerable. This issue has been addressed in commit `4134aedcff1` which has been included in the 5.4 and 6.2 releases. Users are advised to upgrade. There are no known workarounds for this vulnerability.

Weakness:
CWE-74: name: Improper Neutralization of Special Elements in Output Used by a Downstream Component ('Injection')
description: The product constructs all or part of a command, data structure, or record using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify how it is parsed or interpreted when it is sent to a downstream component.

Repository: https://github.com/zopefoundation/RestrictedPython

Vulnerable code:
file_path: src/RestrictedPython/Guards.py
snippet: def safer_getattr(object, name, default=None, getattr=getattr):
    """Getattr implementation which prevents using format on string objects.

    format() is considered harmful:
    http://lucumr.pocoo.org/2016/12/29/careful-with-str-format/

    """
    if isinstance(object, str) and name == 'format':
        raise NotImplementedError(
            'Using format() on a %s is not safe.' % object.__class__.__name__)
    if name.startswith('_'):
        raise AttributeError(
            '"{name}" is an invalid attribute name because it '
            'starts with "_"'.format(name=name)
        )
    return getattr(object, name, default)

file_path: src/RestrictedPython/Utilities.py
snippet: utility_builtins['string'] = string

Fixed code:
file_path: src/RestrictedPython/Guards.py
snippet: def safer_getattr(object, name, default=None, getattr=getattr):
    """Getattr implementation which prevents using format on string objects.

    format() is considered harmful:
    http://lucumr.pocoo.org/2016/12/29/careful-with-str-format/

    """
    if name in ('format', 'format_map') and (
            isinstance(object, str) or
            (isinstance(object, type) and issubclass(object, str))):
        raise NotImplementedError(
            'Using the format*() methods of `str` is not safe')
    if name.startswith('_'):
        raise AttributeError(
            '"{name}" is an invalid attribute name because it '
            'starts with "_"'.format(name=name)
        )
    return getattr(object, name, default)

file_path: src/RestrictedPython/Utilities.py
snippet: 
class _AttributeDelegator:
    def __init__(self, mod, *excludes):
        """delegate attribute lookups outside *excludes* to module *mod*."""
        self.__mod = mod
        self.__excludes = excludes

    def __getattr__(self, attr):
        if attr in self.__excludes:
            raise NotImplementedError(
                f"{self.__mod.__name__}.{attr} is not safe")
        return getattr(self.__mod, attr)


utility_builtins['string'] = _AttributeDelegator(string, "Formatter")