0

I am in a similar position as the individual who asked this question.

I am creating a small utility application that will be shared with 3rd parties as well as used internally and my employer would like us to be able to "maintain control" over the application by preventing unauthorized use.

The protection scheme could be as simple as me distributing a password to those using the application that they then enter into the GUI of the program for authentication. Obviously I cannot hard code the password check in the applications code since they could just edit the code and remove the check.

It is also preferred that the main application code is not easily accessed by those using the application. I understand there are methods to obfuscate and compile the code so that it is difficult to reverse engineer.

Instead of going that route, my thoughts were that I could have the have the application contact a webserver running a flask API that checks the password provided by the user during application run. If it is valid, return code instructions in the response that the client application executes.

I understand that executing code returned from a remote webserver is potentially dangerous, but I am not concerned about it.

Here is the simple scheme I was thinking:

FLASK API ON REMOTE SERVER

from flask import Flask 

PASSWORD = 'demo'


# could maybe read the script file as text and return string instead 
def secret_script_code():
    
    codestring = """
    import math
    
    x = 1
    y = 5
    
    def try_this(x, y):    
        return math.sqrt((y-x))
        
    if __name__ == "__main__":
    
        result = try_this(x, y)        
    """
    return codestring


app = Flask(__name__)


@app.route('/', methods = ['GET','POST'])
def index():        
    if request.method == 'POST': 
        #read the password from the request
        password = request.form['password']        
        if password == PASSWORD:            
            #send python script as string for client to execute            
            return secret_script_code()            
    else:        
        return "print('Invalid!')'"

if __name__ == '__main__':
    app.run()

CLIENT APPLICATION

import requests


payload = {'password': 'demo'}


def run_program(payload):
    # send post request to flask endpoint
    r = requests.post("https://xxx.xx.xx.x/", data=payload)
    # execute the text returned from post request as code
    exec(r.text) 
    
    
if __name__ == "__main__":
    
    run_program(payload)

I understand that if the application user wanted to see the "secret code" that could just add a print() statement to print the string that exec() is executing. Perhaps compiling the code string into bytecode and sending that would be better?

I know all code can be decompiled and there's no real way to protect code from those with the motivation to reverse engineer it. No one is going to waste their time doing that here. But there is a genuine need to try to retain control over application use and prevent it from being easily copied.

E_net4
  • 27,810
  • 13
  • 101
  • 139
unbutu
  • 3
  • 2
  • 1
    If you've already got a central server for the program to connect to, it might make more sense to just have everything important run server-side. – user2357112 Dec 11 '22 at 23:21
  • 1
    I suggest using `ast.literal_eval()` instead of `exec()` as is it safer. I don't know if there are any good obfuscators for Python, maybe it would be better to write code in Cython and distribute a pre-compiled module? – NotAName Dec 11 '22 at 23:27
  • Pure Python local code is very, very easy to bypass. Dropbox tried that for years, but it's always a game of cat and mouse. If you fear that people with sufficient knowledge will try to circumvent simple measures, then either make it web-based (very effective) or search for an obfuscator tool : `python-obfuscator` is a joke, but [pyarmor](https://pypi.org/project/pyarmor/) may suit your need while not totally free. See https://stackoverflow.com/q/3344115/11384184 – Lenormju Dec 12 '22 at 15:26

0 Answers0