Security and the global issue

During unpickling, a global name in the pickle stream can lead to the evaluation of arbitrary code. Generally, the global names inserted into the bytes are class names or a function name. However, it's possible to include a global name that is a function in a module such as os or subprocess. This allows an attack on an application that attempts to transmit pickled objects through the internet without strong SSL controls in place. In order to prevent the execution of arbitrary code, we must extend the pickle.Unpickler class. We'll override the find_class() method to replace it with something more secure. We have to account for several unpickling issues, such as the following:

  • We have to prevent the use of the built-in exec() and eval() functions.
  • We have to prevent the use of modules and packages that might be considered unsafe. For example, sys and os should be prohibited.
  • We have to permit the use of our application modules.

Here's an example that imposes some restrictions:

import builtins

class RestrictedUnpickler(pickle.Unpickler):

def find_class(self, module: str, name: str) -> Any:
if module == "builtins":
if name not in ("exec", "eval"):
return getattr(builtins, name)
elif module in ("__main__", "Chapter_10.ch10_ex3", "ch10_ex3"):
# Valid module names depends on execution context.
return globals()[name]
# elif module in any of our application modules...
elif module in ("Chapter_10.ch10_ex2",):
return globals()[name]
raise pickle.UnpicklingError(
f"global '{module}.{name}' is forbidden"
)

This version of the Unpickler class will help us avoid a large number of potential problems that could stem from a pickle stream that was doctored. It permits the use of any built-in function except exec() and eval(). It permits the use of classes defined only in __main__. In all other cases, it raises an exception.

Let's see how to dump and load using CSV.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset