1

I can use

python -m py_compile mytest.py

And it will byte-compile the file. From reading some other documentation, it was my impression that it byte-compiled any modules imported. But if I change any of the files it imports, I see the changed functionality. Is there some way to completely compile a python script and modules it imports, so that any changes to the originals don't reflect? I want to do this for security purposes, essentially creating a "trusted" version which can't be subverted by changing the functionality of any modules that it calls.

Michael
  • 9,060
  • 14
  • 61
  • 123
  • Security through obscurity is not security. Even statically compiled C can be decompild and modified. – James Mills Jul 19 '14 at 23:03
  • Possible duplicate of http://stackoverflow.com/questions/11368304/what-are-the-limitations-of-distributing-pyc-files – user3856843 Jul 19 '14 at 23:04
  • @JamesMills It's not exactly security through obscurity. I just need a single self-contained file which a more secure process can check before allowing it to run. Have to check an arbitrary number of files first is a bit too much. – Michael Jul 19 '14 at 23:05
  • Let the checking process verify the integrity of the source file being executed by using cryptographic hashes. (i.e: SHA1). Of course this assumes the "checking process" is also secure and cannot be tampered with. – James Mills Jul 19 '14 at 23:07
  • @JamesMills yes, exactly – Michael Jul 19 '14 at 23:13

3 Answers3

2

If you compile to bytecode, then delete the source files, then the bytecode can't change. But if someone has the ability to change source files on your machine, they can also change bytecode files on your machine. I don't think this will give you any actual security.

If you want a single-file Python program, you can run from a zip file.

Another option is to use cx_freeze or a similar program to compile the program into a native executable.

Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
  • I need a single file, apparently deleting the bytecode file for imported modules doesn't work because it needs those files. – Michael Jul 19 '14 at 23:06
  • @Michael you should have said something about single file in the first place! I've updated my answer. – Ned Batchelder Jul 19 '14 at 23:07
  • Thanks I'll look at both of those, they look promising. – Michael Jul 19 '14 at 23:09
  • "cx_Freeze does not support building a single file exe, where all of the libraries for your application are embedded in one executable file." and I can't figure out a way to re-link the executable against the given `.so` files... – Michael Jul 19 '14 at 23:31
2

We solved this problem by developing our own customer loader using signet http://jamercee.github.io/signet/. Signet will scan your python source and it's dependencies and calculate sha1 hashes, which it embeds in the loader. You deliver the loader AND your script to your users with instructions they run the loader. On invocation, it re-calculates the hashes and if they match, control is then transferred to your script. Signet also supports code signing and PE verification.

user590028
  • 11,364
  • 3
  • 40
  • 57
1

Freeze/Bundle:

Cryptography:

Assuming your "process" for running "scripts" is secure and cannot be tampered with:

  • Create secure hashes of the scripts and record them (e.g: SHA1)
  • When executing "scripts" ensure their cryptographic hashes match (ensuring they haven't been tampered with).

A common approach to this for secure protocols and apis is to use HMAC

James Mills
  • 18,669
  • 3
  • 49
  • 62