Wednesday, 28 November 2018

How to dynamically import an unsafe Python module with a timeout?

I need to dynamically load several potentially unsafe modules for testing purpose.

Regarding security, my script is executed by a low-access user.

Although, I still need a way to elegantly make the import process timeout as I have no guarantee that the module script will terminate. By example, it could contain a call to input or an infinite loop.

I am currently using Thread.join with a timeout, but this does not fully solve the issue since the script is then still alive in the background and there is no way to kill a thread.

from threading import Thread
import importlib.util

class ReturnThread(Thread):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._return = None

    def run(self):
        if self._target is not None:
            self._return = self._target(*self._args, **self._kwargs)

    def join(self, *args, **kwargs):
        super().join(*args, **kwargs)
        return self._return

def loader(name, path):
    spec = importlib.util.spec_from_file_location(name, path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module) # This may run into an infinite loop
    return module

module_loader = ReturnThread(loader, ('module_name', 'module/path'))
module_loader.start()
module = module_loader.join(timeout=0.1)

# The thread might still be alive here
if module is None:
    ...
else:
    ...

How can I import a module, but return None if the script timeouts?



from How to dynamically import an unsafe Python module with a timeout?

No comments:

Post a Comment