2

I want to load Python code (if possible with an arbitrary file-extension or even from memory, source or binary) without adding it to sys.modules. Using imp.load_source works for loading a file but the returned module is added to sys.modules and might even be joined with an existing module (see this question)!

So, what I'm currently doing is using the __import__() built-in. Although it allows me to import from a package, I can not load an arbitrary file.

try:
    m = __import__(name)
    for n in name.split('.')[1:]:
        m = getattr(m, n)
    return m
except:
    raise
finally:
    # Restore the old module configuration. Only modules that have
    # not been in sys.path before will be removed.
    for k, v in sys.modules.items():
        if k not in prev_modules and self.is_local(v) or not v:
            del sys.modules[k]
        else:
            sys.modules[k] = v
  1. Removing all modules that haven't been in before the import is a very hacky approach to me.
  2. When a module with the name already exists, it is not reloaded.
  3. I can not load an arbitrary file or even from memory.

I am trying to avoid the exec statement because of security reasons. The source evaluated by exec could hack in to my application using sys._getframe() (and there sure are many more possibilities to do). I have looked at the implementation of the django load tag, but that just uses __import_() as well.

Is there a way to load Python code (either source or binary) from a file (or even memory) that is secure, self-contained (no adding interaction with sys.modules)? In the best case, it would not only allow me to load a file and from memory, but also load a complete package like the __import__() function.

3
  • I think the word secure and self-contained is an impossible combination here. AFAIK, importing a python module effectively executes it. The closest thing I know is seattle.cs.washington.edu/browser/seattle/branches/repy_v2/repy/…, which is attempts to build a safe exec. It's based on statically analyzing the code and removing access to 'dangerous' built-in's. Commented Mar 18, 2013 at 12:48
  • I just created a first GitHub gist related to loading command-line scripts as modules. The code could be modified to skip storing the module in sys.modules. gist.github.com/DanielMGessel/f92bf80e199e23e2a250567980e0bf8e Commented Aug 5, 2022 at 19:01
  • You might want to take a look at localimport. (Disclaimer: I am the author of this package) Commented Aug 8, 2022 at 9:28

1 Answer 1

1

Using the CPython interpreter, I don't believe this is possible. However, PyPy provides a sandboxed environment that makes what you want to do quite easy.

Look at the PyPy documentation on sandboxing for details.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.