diff --git a/src/RestrictedPython/Guards.py b/src/RestrictedPython/Guards.py index 9b70ae3..f46f80a 100644 --- a/src/RestrictedPython/Guards.py +++ b/src/RestrictedPython/Guards.py @@ -244,11 +244,12 @@ def safer_getattr(object, name, default=None, getattr=getattr): format() is considered harmful: http://lucumr.pocoo.org/2016/12/29/careful-with-str-format/ + format_map() is equivalent to format with dict as argument. """ - if isinstance(object, str) and name == 'format': + if isinstance(object, str) and name in ('format', 'format_map'): raise NotImplementedError( - 'Using format() on a %s is not safe.' % object.__class__.__name__) + 'Using %s() on a %s is not safe.' % (name, object.__class__.__name__)) if name.startswith('_'): raise AttributeError( '"{name}" is an invalid attribute name because it ' diff --git a/tests/test_Guards.py b/tests/test_Guards.py index bd61ec7..2e2b9eb 100644 --- a/tests/test_Guards.py +++ b/tests/test_Guards.py @@ -219,6 +219,26 @@ def test_Guards__safer_getattr__3(): assert restricted_globals['result'] == 2 +STRING_DOT_FORMAT_MAP_DENIED = """\ +a = 'Hello {name}' +b = a.format_map({name: 'world'}) +""" + + +def test_Guards__safer_getattr__4(): + """It prevents using the format_map method of a string. + + format_map() is similar to format() + http://lucumr.pocoo.org/2016/12/29/careful-with-str-format/ + """ + glb = { + '__builtins__': safe_builtins, + } + with pytest.raises(NotImplementedError) as err: + restricted_exec(STRING_DOT_FORMAT_DENIED, glb) + assert 'Using format() on a str is not safe.' == str(err.value) + + def test_call_py3_builtins(): """It should not be allowed to access global builtins in Python3.""" result = compile_restricted_exec('builtins["getattr"]')