|
7 | 7 | # Imports |
8 | 8 | #------------------------------------------------------------------------------ |
9 | 9 |
|
| 10 | +import hashlib |
10 | 11 | # Stdlib |
11 | | -import inspect, os, sys, textwrap, re |
| 12 | +import io |
| 13 | +import os |
| 14 | +import re |
| 15 | +import sys |
12 | 16 |
|
13 | 17 | # Our own |
14 | 18 | from IPython.config.configurable import Configurable |
15 | 19 | from IPython.core import magic_arguments |
16 | | -from IPython.core.magic import Magics, magics_class, line_magic, cell_magic |
17 | | -from IPython.utils.traitlets import Unicode |
18 | | -from IPython.utils.io import CapturedIO, capture_output |
| 20 | +from IPython.core.magic import Magics, magics_class, cell_magic |
19 | 21 | from IPython.display import clear_output |
20 | | -import hashlib |
21 | | - |
| 22 | +from IPython.utils.io import CapturedIO |
| 23 | +from IPython.utils.traitlets import Unicode |
22 | 24 |
|
23 | 25 | #------------------------------------------------------------------------------ |
24 | 26 | # Six utility functions for Python 2/3 compatibility |
@@ -115,6 +117,7 @@ def load_vars(path, vars): |
115 | 117 | with open(path, 'rb') as f: |
116 | 118 | # Load the variables from the cache. |
117 | 119 | try: |
| 120 | + restricted_loads(f.read()) |
118 | 121 | cache = pickle.load(f) |
119 | 122 | except EOFError as e: |
120 | 123 | cache={} |
@@ -151,8 +154,26 @@ def save_vars(path, vars_d): |
151 | 154 | """ |
152 | 155 | with open(path, 'wb') as f: |
153 | 156 | dump(vars_d, f) |
154 | | - |
155 | | - |
| 157 | + |
| 158 | + |
| 159 | +# ------------------------------------------------------------------------------ |
| 160 | +# RestrictedUnpickler - For mitigating arbitrary code execution while unpickling |
| 161 | +# This function provides restriction of using only the io module |
| 162 | +# ------------------------------------------------------------------------------ |
| 163 | +class RestrictedUnpickler(pickle.Unpickler): |
| 164 | + |
| 165 | + def find_class(self, module, name): |
| 166 | + if module == '_io' and name == 'StringIO': |
| 167 | + return getattr(sys.modules[module], name) |
| 168 | + # Forbid everything else. |
| 169 | + raise pickle.UnpicklingError("global '%s.%s' is forbidden" % |
| 170 | + (module, name)) |
| 171 | + |
| 172 | + |
| 173 | +def restricted_loads(s): |
| 174 | + """Helper function analogous to pickle.loads().""" |
| 175 | + return RestrictedUnpickler(io.BytesIO(s)).load() |
| 176 | + |
156 | 177 | #------------------------------------------------------------------------------ |
157 | 178 | # CapturedIO |
158 | 179 | #------------------------------------------------------------------------------ |
|
0 commit comments