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.