0

I am trying to see if I can protect my python source code in the following scenario:

  1. I am managing a linux server, where I am the only one to have root privileges
  2. My users have separated user accounts on this server
  3. I want to find a way to install a private pure-python module on this server so that my users may import that module, without them being able to access the code

Is there a way to do such a thing?

MarkoPaulo
  • 474
  • 4
  • 19
  • 1
    It sounds like you might want to use other means of providing a secure interface. You should look into using containers for each user, perhaps a setup with RestrictedPython (do your own research) for crippling user-submitted code, if that's the goal. I hate to ask, but why is this necessary? It might provide some more context. Is this in an office setting? – Audiopolis Jul 06 '21 at 00:12
  • 1
    Not sure if reading of something is possible without read access rights. At least you can try to compile python code (into .pyc), not sure if this secure, and how easy it may be decompiled. Another way is to create stand-alone rest api service and run it on different server. – rzlvmp Jul 06 '21 at 00:18
  • @Audiopolis, this is a sort of service-provider/client setting. I am providing python libraries to clients on that server, and I don't want them to be able to "steal the code" and run away. – MarkoPaulo Jul 06 '21 at 03:45

2 Answers2

1

It sounds like you want a code obfuscation tool, which makes code unreadable without some very dedicated reverse engineering by renaming variables, functions, modules, etc., replacing their names with gibberish.

If a computer can execute code, then someone with admin access to that computer can also read the compiled code, no exceptions. If you don't want someone to steal your logic, you obfuscate. If you don't want people to pirate your software (use it without paying), you can add some software protections (research how other subscription software is protected) and obfuscate those as well, so that it's hard to bypass the restrictions and clearly in breach of IP laws.

Alternatively (if suitable, which it usually is), you might want to run the code on your own server and publish an API for your customers to use. For their convenience, you might also develop an abstraction of the public API for clients to use. This won't let clients access code at all; clients indirectly ask the server to do something, and the server does it if everything is in order (the client has a valid subscription, for example).

Audiopolis
  • 530
  • 5
  • 24
0

Check out this page: https://www.packagr.app/?ref=Medium

The private package function costs $10 a month. If you can pay it, go ahead with this process of installation, link below:

https://medium.com/packagr/creating-and-sharing-private-python-packages-151a95e10735

If you are not able to pay the requested price, there are other ways to achieve the full privacy of the package. You can use the .pyc extension. This type of file is automatically created by python when you locally import a module. The content of this file is the original module but in bytes format. The problem is that you cannot execute or 'import' this kind of file by just simply importing it in a single line. To execute this kind of file you need to do this.

  1. Have your original module source code, for example this:

     def abc():
        countries = ["United States", "Poland", "Russia", "Portugal", "France", "Germany"]
        for country in countries:
            print(country)
     if __name__ == "__main__":
        print("countries")
    
  2. Then you compile the file into a .pyc. This can be done using the module "py_compile":

     py_compile.compile('test.py', 'mypyc.pyc')
    
  3. Then you should provide the server just this file. In order to use it, each user in the server will need to add this lines to ther files:

     import marshal
    
     s = open('mypyc.pyc', 'rb')
     s.seek(8)  # go past first eight bytes
     code_obj = marshal.load(s)
    
  4. Then, execute the code_obj:

     exec(code_obj)
    
  5. Finally, you can use the function of the module. In the case of this example:

     abc()
    

But for the moment, the content of the module can be seen through:

print(code_obj)

Which makes the thing useless. What you can do is restrict console output by using:

sudo dmesg -n 1

If you do this, you restrict every single output of the console. So, you can force users to redirect the output of the program to a new file and then read that file through vim. But, another problem comes up, they can write the source code of the module to a new file by doing this:

with open('readme.txt', 'w') as f:
  f.write(code_obj)

Then, you should create a bash file that is constantly running that restricts the creation of files that contains a specific set of eight characters at the beginning. Then, add this eight-byte combination at the beginning of your module. In this way, you prevent users from copying the module. Probably there are more options available, but I think that this can solve your problem.

SGD
  • 45
  • 2
  • 7