If the attacker is able to alter sys.path then it does not matter
whether zipfiles are even considered -- the attacker could simply
position a .pyc file early on the path.
This could be made to work, but only if _every_ module was so checked
before importing it; otherwise, even just one unchecked module could
easily subvert __import__ or other aspects of the import hook mechanism.
So, if you're considering this approach, it makes more sense to switch
on module checking globally in an early phase of Python's startup
(because Python starts importing modules pretty early indeed). New
conventions will also be needed for signature of .py, .pyc, .pyo, and
.so (or other binary DLLoid files containing Python extensions).
It doesn't look like anyone has mentioned the Python Cryptography
Toolkit in this thread yet. (I have no affiliation with said project)
http://www.amk.ca/python/code/crypto.html
http://www.amk.ca/python/writing/pycrypt/pycrypt.html :
7.2 Demo 2: secimp and sign
secimp demonstrates an application of the Toolkit that may be useful
if Python is being used as an extension language for mail and Web
clients: secure importing of Python modules. To use it, run sign.py
in a directory with several compiled Python files present. It will
use the key in testkey.py to generate digital signatures for the
compiled Python code, and save both the signature and the code in a
file ending in ".pys". Then run python -i secimp.py, and import a
file by using secimport.
For example, if foo.pys was constructed, do secimport('foo'). The
import should succeed. Now fire up Emacs or some other editor, and
change a string in the code in foo.pys; you might try changing a
letter in the name of a variable. When you run secimport('foo'), it
should raise an exception reporting the failed signature. If you
execute the statement __import__ = secimport, the secure import will
be used by default for all future module imports. Alternatively, if
you were creating a restricted execution environment using rexec.py,
you could place secimport() in the restricted environment's
namespace as the default import function.
-Steve