RestrictedPython 7.3__py3-none-any.whl → 8.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- RestrictedPython/Guards.py +10 -5
- RestrictedPython/_compat.py +0 -1
- RestrictedPython/transformer.py +29 -83
- {RestrictedPython-7.3.dist-info → RestrictedPython-8.0.dist-info}/METADATA +46 -12
- RestrictedPython-8.0.dist-info/RECORD +14 -0
- {RestrictedPython-7.3.dist-info → RestrictedPython-8.0.dist-info}/WHEEL +1 -1
- RestrictedPython-7.3.dist-info/RECORD +0 -14
- {RestrictedPython-7.3.dist-info → RestrictedPython-8.0.dist-info}/LICENSE.txt +0 -0
- {RestrictedPython-7.3.dist-info → RestrictedPython-8.0.dist-info}/top_level.txt +0 -0
RestrictedPython/Guards.py
CHANGED
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
|
|
18
18
|
import builtins
|
|
19
19
|
|
|
20
|
-
from RestrictedPython._compat import IS_PY311_OR_GREATER
|
|
21
20
|
from RestrictedPython.transformer import INSPECT_ATTRIBUTES
|
|
22
21
|
|
|
23
22
|
|
|
@@ -106,9 +105,6 @@ _safe_exceptions = [
|
|
|
106
105
|
'ZeroDivisionError',
|
|
107
106
|
]
|
|
108
107
|
|
|
109
|
-
if IS_PY311_OR_GREATER:
|
|
110
|
-
_safe_exceptions.append("ExceptionGroup")
|
|
111
|
-
|
|
112
108
|
for name in _safe_names:
|
|
113
109
|
safe_builtins[name] = getattr(builtins, name)
|
|
114
110
|
|
|
@@ -240,6 +236,9 @@ def guarded_delattr(object, name):
|
|
|
240
236
|
safe_builtins['delattr'] = guarded_delattr
|
|
241
237
|
|
|
242
238
|
|
|
239
|
+
raise_ = object()
|
|
240
|
+
|
|
241
|
+
|
|
243
242
|
def safer_getattr(object, name, default=None, getattr=getattr):
|
|
244
243
|
"""Getattr implementation which prevents using format on string objects.
|
|
245
244
|
|
|
@@ -263,12 +262,18 @@ def safer_getattr(object, name, default=None, getattr=getattr):
|
|
|
263
262
|
'"{name}" is an invalid attribute name because it '
|
|
264
263
|
'starts with "_"'.format(name=name)
|
|
265
264
|
)
|
|
266
|
-
|
|
265
|
+
args = (object, name) + (() if default is raise_ else (default,))
|
|
266
|
+
return getattr(*args)
|
|
267
267
|
|
|
268
268
|
|
|
269
269
|
safe_builtins['_getattr_'] = safer_getattr
|
|
270
270
|
|
|
271
271
|
|
|
272
|
+
def safer_getattr_raise(object, name, default=raise_):
|
|
273
|
+
"""like ``safer_getattr`` but raising ``AttributeError`` if failing."""
|
|
274
|
+
return safer_getattr(object, name, default)
|
|
275
|
+
|
|
276
|
+
|
|
272
277
|
def guarded_iter_unpack_sequence(it, spec, _getiter_):
|
|
273
278
|
"""Protect sequence unpacking of targets in a 'for loop'.
|
|
274
279
|
|
RestrictedPython/_compat.py
CHANGED
|
@@ -3,7 +3,6 @@ import sys
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
_version = sys.version_info
|
|
6
|
-
IS_PY38_OR_GREATER = _version.major == 3 and _version.minor >= 8
|
|
7
6
|
IS_PY310_OR_GREATER = _version.major == 3 and _version.minor >= 10
|
|
8
7
|
IS_PY311_OR_GREATER = _version.major == 3 and _version.minor >= 11
|
|
9
8
|
IS_PY312_OR_GREATER = _version.major == 3 and _version.minor >= 12
|
RestrictedPython/transformer.py
CHANGED
|
@@ -22,16 +22,6 @@ import ast
|
|
|
22
22
|
import contextlib
|
|
23
23
|
import textwrap
|
|
24
24
|
|
|
25
|
-
from ._compat import IS_PY38_OR_GREATER
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
# Avoid DeprecationWarnings under Python 3.12 and up
|
|
29
|
-
if IS_PY38_OR_GREATER:
|
|
30
|
-
astStr = ast.Constant
|
|
31
|
-
astNum = ast.Constant
|
|
32
|
-
else: # pragma: no cover
|
|
33
|
-
astStr = ast.Str
|
|
34
|
-
astNum = ast.Num
|
|
35
25
|
|
|
36
26
|
# For AugAssign the operator must be converted to a string.
|
|
37
27
|
IOPERATOR_TO_STR = {
|
|
@@ -127,16 +117,14 @@ def copy_locations(new_node, old_node):
|
|
|
127
117
|
assert 'lineno' in new_node._attributes
|
|
128
118
|
new_node.lineno = old_node.lineno
|
|
129
119
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
new_node.end_lineno = old_node.end_lineno
|
|
120
|
+
assert 'end_lineno' in new_node._attributes
|
|
121
|
+
new_node.end_lineno = old_node.end_lineno
|
|
133
122
|
|
|
134
123
|
assert 'col_offset' in new_node._attributes
|
|
135
124
|
new_node.col_offset = old_node.col_offset
|
|
136
125
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
new_node.end_col_offset = old_node.end_col_offset
|
|
126
|
+
assert 'end_col_offset' in new_node._attributes
|
|
127
|
+
new_node.end_col_offset = old_node.end_col_offset
|
|
140
128
|
|
|
141
129
|
ast.fix_missing_locations(new_node)
|
|
142
130
|
|
|
@@ -280,7 +268,7 @@ class RestrictingNodeTransformer(ast.NodeTransformer):
|
|
|
280
268
|
"""
|
|
281
269
|
spec = ast.Dict(keys=[], values=[])
|
|
282
270
|
|
|
283
|
-
spec.keys.append(
|
|
271
|
+
spec.keys.append(ast.Constant('childs'))
|
|
284
272
|
spec.values.append(ast.Tuple([], ast.Load()))
|
|
285
273
|
|
|
286
274
|
# starred elements in a sequence do not contribute into the min_len.
|
|
@@ -300,12 +288,12 @@ class RestrictingNodeTransformer(ast.NodeTransformer):
|
|
|
300
288
|
|
|
301
289
|
elif isinstance(val, ast.Tuple):
|
|
302
290
|
el = ast.Tuple([], ast.Load())
|
|
303
|
-
el.elts.append(
|
|
291
|
+
el.elts.append(ast.Constant(idx - offset))
|
|
304
292
|
el.elts.append(self.gen_unpack_spec(val))
|
|
305
293
|
spec.values[0].elts.append(el)
|
|
306
294
|
|
|
307
|
-
spec.keys.append(
|
|
308
|
-
spec.values.append(
|
|
295
|
+
spec.keys.append(ast.Constant('min_len'))
|
|
296
|
+
spec.values.append(ast.Constant(min_len))
|
|
309
297
|
|
|
310
298
|
return spec
|
|
311
299
|
|
|
@@ -492,9 +480,8 @@ class RestrictingNodeTransformer(ast.NodeTransformer):
|
|
|
492
480
|
if isinstance(node, ast.Module):
|
|
493
481
|
_print.lineno = position
|
|
494
482
|
_print.col_offset = position
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
_print.end_col_offset = position
|
|
483
|
+
_print.end_lineno = position
|
|
484
|
+
_print.end_col_offset = position
|
|
498
485
|
ast.fix_missing_locations(_print)
|
|
499
486
|
else:
|
|
500
487
|
copy_locations(_print, node)
|
|
@@ -535,63 +522,22 @@ class RestrictingNodeTransformer(ast.NodeTransformer):
|
|
|
535
522
|
|
|
536
523
|
# ast for Literals
|
|
537
524
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
def visit_Constant(self, node):
|
|
541
|
-
"""Allow constant literals with restriction for Ellipsis.
|
|
542
|
-
|
|
543
|
-
Constant replaces Num, Str, Bytes, NameConstant and Ellipsis in
|
|
544
|
-
Python 3.8+.
|
|
545
|
-
:see: https://docs.python.org/dev/whatsnew/3.8.html#deprecated
|
|
546
|
-
"""
|
|
547
|
-
if node.value is Ellipsis:
|
|
548
|
-
# Deny using `...`.
|
|
549
|
-
# Special handling necessary as ``self.not_allowed(node)``
|
|
550
|
-
# would return the Error Message:
|
|
551
|
-
# 'Constant statements are not allowed.'
|
|
552
|
-
# which is only partial true.
|
|
553
|
-
self.error(node, 'Ellipsis statements are not allowed.')
|
|
554
|
-
return
|
|
555
|
-
return self.node_contents_visit(node)
|
|
556
|
-
|
|
557
|
-
else:
|
|
558
|
-
|
|
559
|
-
def visit_Num(self, node):
|
|
560
|
-
"""Allow integer numbers without restrictions.
|
|
561
|
-
|
|
562
|
-
Replaced by Constant in Python 3.8.
|
|
563
|
-
"""
|
|
564
|
-
return self.node_contents_visit(node)
|
|
565
|
-
|
|
566
|
-
def visit_Str(self, node):
|
|
567
|
-
"""Allow string literals without restrictions.
|
|
568
|
-
|
|
569
|
-
Replaced by Constant in Python 3.8.
|
|
570
|
-
"""
|
|
571
|
-
return self.node_contents_visit(node)
|
|
572
|
-
|
|
573
|
-
def visit_Bytes(self, node):
|
|
574
|
-
"""Allow bytes literals without restrictions.
|
|
525
|
+
def visit_Constant(self, node):
|
|
526
|
+
"""Allow constant literals with restriction for Ellipsis.
|
|
575
527
|
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
restrictions.
|
|
591
|
-
|
|
592
|
-
Replaced by Constant in Python 3.8.
|
|
593
|
-
"""
|
|
594
|
-
return self.node_contents_visit(node)
|
|
528
|
+
Constant replaces Num, Str, Bytes, NameConstant and Ellipsis in
|
|
529
|
+
Python 3.8+.
|
|
530
|
+
:see: https://docs.python.org/dev/whatsnew/3.8.html#deprecated
|
|
531
|
+
"""
|
|
532
|
+
if node.value is Ellipsis:
|
|
533
|
+
# Deny using `...`.
|
|
534
|
+
# Special handling necessary as ``self.not_allowed(node)``
|
|
535
|
+
# would return the Error Message:
|
|
536
|
+
# 'Constant statements are not allowed.'
|
|
537
|
+
# which is only partial true.
|
|
538
|
+
self.error(node, 'Ellipsis statements are not allowed.')
|
|
539
|
+
return
|
|
540
|
+
return self.node_contents_visit(node)
|
|
595
541
|
|
|
596
542
|
def visit_Interactive(self, node):
|
|
597
543
|
"""Allow single mode without restrictions."""
|
|
@@ -915,7 +861,7 @@ class RestrictingNodeTransformer(ast.NodeTransformer):
|
|
|
915
861
|
node = self.node_contents_visit(node)
|
|
916
862
|
new_node = ast.Call(
|
|
917
863
|
func=ast.Name('_getattr_', ast.Load()),
|
|
918
|
-
args=[node.value,
|
|
864
|
+
args=[node.value, ast.Constant(node.attr)],
|
|
919
865
|
keywords=[])
|
|
920
866
|
|
|
921
867
|
copy_locations(new_node, node)
|
|
@@ -1119,7 +1065,7 @@ class RestrictingNodeTransformer(ast.NodeTransformer):
|
|
|
1119
1065
|
value=ast.Call(
|
|
1120
1066
|
func=ast.Name('_inplacevar_', ast.Load()),
|
|
1121
1067
|
args=[
|
|
1122
|
-
|
|
1068
|
+
ast.Constant(IOPERATOR_TO_STR[type(node.op)]),
|
|
1123
1069
|
ast.Name(node.target.id, ast.Load()),
|
|
1124
1070
|
node.value
|
|
1125
1071
|
],
|
|
@@ -1195,8 +1141,8 @@ class RestrictingNodeTransformer(ast.NodeTransformer):
|
|
|
1195
1141
|
return self.node_contents_visit(node)
|
|
1196
1142
|
|
|
1197
1143
|
def visit_TryStar(self, node):
|
|
1198
|
-
"""
|
|
1199
|
-
|
|
1144
|
+
"""Disallow `ExceptionGroup` due to a potential sandbox escape."""
|
|
1145
|
+
self.not_allowed(node)
|
|
1200
1146
|
|
|
1201
1147
|
def visit_ExceptHandler(self, node):
|
|
1202
1148
|
"""Protect exception handlers."""
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: RestrictedPython
|
|
3
|
-
Version:
|
|
3
|
+
Version: 8.0
|
|
4
4
|
Summary: RestrictedPython is a defined subset of the Python language which allows to provide a program input into a trusted environment.
|
|
5
5
|
Home-page: https://github.com/zopefoundation/RestrictedPython
|
|
6
6
|
Author: Zope Foundation and Contributors
|
|
7
|
-
Author-email: zope-dev@zope.
|
|
8
|
-
License: ZPL
|
|
7
|
+
Author-email: zope-dev@zope.dev
|
|
8
|
+
License: ZPL-2.1
|
|
9
9
|
Project-URL: Documentation, https://restrictedpython.readthedocs.io/
|
|
10
10
|
Project-URL: Source, https://github.com/zopefoundation/RestrictedPython
|
|
11
11
|
Project-URL: Tracker, https://github.com/zopefoundation/RestrictedPython/issues
|
|
@@ -15,23 +15,22 @@ Classifier: License :: OSI Approved :: Zope Public License
|
|
|
15
15
|
Classifier: Programming Language :: Python
|
|
16
16
|
Classifier: Operating System :: OS Independent
|
|
17
17
|
Classifier: Programming Language :: Python :: 3
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
20
18
|
Classifier: Programming Language :: Python :: 3.9
|
|
21
19
|
Classifier: Programming Language :: Python :: 3.10
|
|
22
20
|
Classifier: Programming Language :: Python :: 3.11
|
|
23
21
|
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
23
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
25
24
|
Classifier: Topic :: Security
|
|
26
|
-
Requires-Python: >=3.
|
|
25
|
+
Requires-Python: >=3.9, <3.14
|
|
27
26
|
Description-Content-Type: text/x-rst
|
|
28
27
|
License-File: LICENSE.txt
|
|
29
|
-
Provides-Extra: docs
|
|
30
|
-
Requires-Dist: Sphinx ; extra == 'docs'
|
|
31
|
-
Requires-Dist: sphinx-rtd-theme ; extra == 'docs'
|
|
32
28
|
Provides-Extra: test
|
|
33
|
-
Requires-Dist: pytest
|
|
34
|
-
Requires-Dist: pytest-mock
|
|
29
|
+
Requires-Dist: pytest; extra == "test"
|
|
30
|
+
Requires-Dist: pytest-mock; extra == "test"
|
|
31
|
+
Provides-Extra: docs
|
|
32
|
+
Requires-Dist: Sphinx; extra == "docs"
|
|
33
|
+
Requires-Dist: furo; extra == "docs"
|
|
35
34
|
|
|
36
35
|
.. image:: https://github.com/zopefoundation/RestrictedPython/actions/workflows/tests.yml/badge.svg
|
|
37
36
|
:target: https://github.com/zopefoundation/RestrictedPython/actions/workflows/tests.yml
|
|
@@ -124,6 +123,41 @@ the documentation `Contributing page
|
|
|
124
123
|
Changes
|
|
125
124
|
=======
|
|
126
125
|
|
|
126
|
+
8.0 (2025-01-23)
|
|
127
|
+
----------------
|
|
128
|
+
|
|
129
|
+
Backwards incompatible changes
|
|
130
|
+
++++++++++++++++++++++++++++++
|
|
131
|
+
|
|
132
|
+
- Disallow ``try/except*`` clauses due to a possible sandbox escape and
|
|
133
|
+
probable uselessness of this feature in the context of ``RestrictedPython``.
|
|
134
|
+
In addition, remove ``ExceptionGroup`` from ``safe_builtins`` (as useful only
|
|
135
|
+
with ``try/except*``). - This feature was introduced into
|
|
136
|
+
``RestrictedPython`` in version 6.0 for Python 3.11+. (CVE-2025-22153)
|
|
137
|
+
|
|
138
|
+
- Drop support for Python 3.8.
|
|
139
|
+
|
|
140
|
+
Features
|
|
141
|
+
++++++++
|
|
142
|
+
|
|
143
|
+
- Update setuptools version pin.
|
|
144
|
+
(`#292 <https://github.com/zopefoundation/RestrictedPython/issues/292>`_)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
7.4 (2024-10-09)
|
|
148
|
+
----------------
|
|
149
|
+
|
|
150
|
+
- Allow to use the package with Python 3.13.
|
|
151
|
+
|
|
152
|
+
- Drop support for Python 3.7.
|
|
153
|
+
|
|
154
|
+
- Provide new function ``RestrictedPython.Guards.safer_getattr_raise``.
|
|
155
|
+
It is similar to ``safer_getattr`` but handles its parameter
|
|
156
|
+
``default`` like ``getattr``, i.e. it raises ``AttributeError``
|
|
157
|
+
if the attribute lookup fails and this parameter is not provided,
|
|
158
|
+
fixes `#287 <https://github.com/zopefoundation/RestrictedPython/issues/287>`_.
|
|
159
|
+
|
|
160
|
+
|
|
127
161
|
7.3 (2024-09-30)
|
|
128
162
|
----------------
|
|
129
163
|
|
|
@@ -132,7 +166,7 @@ Changes
|
|
|
132
166
|
and give the same level of protection as direct attribute access in an
|
|
133
167
|
environment based on ``RestrictedPython``'s ``safe_builtints``.
|
|
134
168
|
- Prevent information leakage via ``AttributeError.obj``
|
|
135
|
-
and the ``string`` module.
|
|
169
|
+
and the ``string`` module. (CVE-2024-47532)
|
|
136
170
|
|
|
137
171
|
|
|
138
172
|
7.2 (2024-08-02)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
RestrictedPython/Eval.py,sha256=pa79tc-JsT7xfzwg0ceMkxyioIEnFbNHc_PsKUhkkj8,3201
|
|
2
|
+
RestrictedPython/Guards.py,sha256=hGLMmqB7SPWwaxHl5elPED6MPCLCWg2nmCVM4_OYaV4,8089
|
|
3
|
+
RestrictedPython/Limits.py,sha256=dORpuly21vSjy8gzNac9IYfIXMMWRVFvqUiKKIeZ3OM,1866
|
|
4
|
+
RestrictedPython/PrintCollector.py,sha256=bBCpnUPOuKz1wJDuSgh7wo2aoKfcTJeeT8OYnM-K9F8,1137
|
|
5
|
+
RestrictedPython/Utilities.py,sha256=u4HUdyjGawaeHyXSakyt4gRT17BZietXnF5WqicujjE,3033
|
|
6
|
+
RestrictedPython/__init__.py,sha256=qB_s6zDxuXPAGMoKYKBMc-xZ0gTnQ0ZvtY5FxdAG3aM,1862
|
|
7
|
+
RestrictedPython/_compat.py,sha256=2Mew5xHBB0Lg3YfhbFyTdOSt4TQCWnEBGQ1SNFeR8a0,318
|
|
8
|
+
RestrictedPython/compile.py,sha256=IhcF733t-bkPcvfQ2_NyBeCbSIPtHYxR-GQNNHnaMHM,6727
|
|
9
|
+
RestrictedPython/transformer.py,sha256=UEs-dqbE6r0lGq7JLszVsIXnZTnO_ak2pw8Isyp9l6s,41419
|
|
10
|
+
RestrictedPython-8.0.dist-info/LICENSE.txt,sha256=PmcdsR32h1FswdtbPWXkqjg-rKPCDOo_r1Og9zNdCjw,2070
|
|
11
|
+
RestrictedPython-8.0.dist-info/METADATA,sha256=MgUWJ-boog0VTEnx4DfwdscAQ9wh8fxfj7wmf6exrPY,14023
|
|
12
|
+
RestrictedPython-8.0.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
|
13
|
+
RestrictedPython-8.0.dist-info/top_level.txt,sha256=E1-3ARWcduVJnQAScms0FgqnBx_PovrzYsNMYuLGwa0,17
|
|
14
|
+
RestrictedPython-8.0.dist-info/RECORD,,
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
RestrictedPython/Eval.py,sha256=pa79tc-JsT7xfzwg0ceMkxyioIEnFbNHc_PsKUhkkj8,3201
|
|
2
|
-
RestrictedPython/Guards.py,sha256=YV-gxQZoXXzr7pLF3ovpVdVmKgsQ4LVcET6T-dHEMns,7962
|
|
3
|
-
RestrictedPython/Limits.py,sha256=dORpuly21vSjy8gzNac9IYfIXMMWRVFvqUiKKIeZ3OM,1866
|
|
4
|
-
RestrictedPython/PrintCollector.py,sha256=bBCpnUPOuKz1wJDuSgh7wo2aoKfcTJeeT8OYnM-K9F8,1137
|
|
5
|
-
RestrictedPython/Utilities.py,sha256=u4HUdyjGawaeHyXSakyt4gRT17BZietXnF5WqicujjE,3033
|
|
6
|
-
RestrictedPython/__init__.py,sha256=qB_s6zDxuXPAGMoKYKBMc-xZ0gTnQ0ZvtY5FxdAG3aM,1862
|
|
7
|
-
RestrictedPython/_compat.py,sha256=nacdAJi4E8GKhkR99_BAxMA0AtK2FQnvrqZbG8hGofc,383
|
|
8
|
-
RestrictedPython/compile.py,sha256=IhcF733t-bkPcvfQ2_NyBeCbSIPtHYxR-GQNNHnaMHM,6727
|
|
9
|
-
RestrictedPython/transformer.py,sha256=toPGqFvc9WM1bnh2yIgNZcsz0ySwlSyJXViCSau-19I,42906
|
|
10
|
-
RestrictedPython-7.3.dist-info/LICENSE.txt,sha256=PmcdsR32h1FswdtbPWXkqjg-rKPCDOo_r1Og9zNdCjw,2070
|
|
11
|
-
RestrictedPython-7.3.dist-info/METADATA,sha256=J-IFLeEBGFCNsFn1FitgU1b_fA_dzSV1BfLiuicqLlI,12981
|
|
12
|
-
RestrictedPython-7.3.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
13
|
-
RestrictedPython-7.3.dist-info/top_level.txt,sha256=E1-3ARWcduVJnQAScms0FgqnBx_PovrzYsNMYuLGwa0,17
|
|
14
|
-
RestrictedPython-7.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|