Search code examples
pythonflaskpyinstalleruwsgi

How can I protect my source code when running a Flask application with uWSGI?


I have a Flask application application that I run with uWSGI. My clients have access to the server where the app runs.

How can I protect or hide my source code?

Edit: I found that you can embed an app in uWSGI by building it from source, but that seems far fetched.


Solution

  • True - if someone wants it badly enough, the only way to truly secure your algorithms is not to hand them out. But, reality is that code is hard to understand anyway. Often, just not documenting code is enough to discourage. There are some techniques, however, and your effort varies with how secure they are. Some approaches that come to mind are.

    • Compile to bytecode: I've seen it done in the wild, there was company that made a Python email client for Linux / Outlook. I recall that it was obfuscated through a compiled distribution. You'd have to research the proper tool.

    • Obfuscate at a per-script level: Check out the pyminifier tool. It can make your scripts pretty near impossible to read (but it can be reversed with reasonable effort)

    • Use an advanced obfuscator: Look at pyarmor. It is a lot more complex and will be harder to implement -- but it looks like it would get the job done.

    • Open source it. Seems counter intuitive -- but algorithms are rarely the most valuable aspect of code. Having the skill, time, resources to understand and maintain it is. It is very likely that it doesn't matter if anyone sees your code. If you are giving a good service to your customer, they generally have much better things to do than to take on your code base. There are plenty of enterprise companies making a living from open source software (eg. Startburst, 2nd Quadrant.)

    (Example code obfuscated using pyminifier)

    import argparse
    𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𐤡=range
    𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ枇=int
    𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𧌾=print
    𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆﶾ=argparse.ArgumentParser
    import sys
    𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𑆉=sys.argv
    𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𞤌=sys.stdout
    import logging
    𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ닸=logging.basicConfig
    𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𧄱=logging.DEBUG
    𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ柚=logging.INFO
    𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ䔎=logging.getLogger
    from demo import __version__
    __author__="Steve Jackson"
    __copyright__="Steve Jackson"
    __license__="mit"
    𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𐪕=𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ䔎(__name__)
    def 𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𡈲(n):
     assert n>0
     𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ関,𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𒂻=1,1
     for i in 𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𐤡(n-1):
      𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ関,𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𒂻=𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𒂻,𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ関+𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𒂻
     return 𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ関
    def 𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𐲍(𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𡐮):
     𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆݻ=𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆﶾ(description="Just a Fibonacci demonstration")
     𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆݻ.add_argument("--version",action="version",version="demo-day {ver}".format(ver=__version__))
     𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆݻ.add_argument(dest="n",help="n-th Fibonacci number",type=𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ枇,metavar="INT")
     𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆݻ.add_argument("-v","--verbose",dest="loglevel",help="set loglevel to INFO",action="store_const",const=𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ柚)
     𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆݻ.add_argument("-vv","--very-verbose",dest="loglevel",help="set loglevel to DEBUG",action="store_const",const=𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𧄱)
     return 𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆݻ.𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𐲍(𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𡐮)
    def 𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𐮑(loglevel):
     𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𗰆="[%(asctime)s] %(levelname)s:%(name)s:%(message)s"
     𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ닸(level=loglevel,stream=𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𞤌,format=𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𗰆,datefmt="%Y-%m-%d %H:%M:%S")
    def 𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆﯜ(𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𡐮):
     𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𡐮=𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𐲍(𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𡐮)
     𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𐮑(𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𡐮.loglevel)
     𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𐪕.debug("Starting crazy calculations...")
     𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𧌾("The {}-th Fibonacci number is {}".format(𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𡐮.n,𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𡈲(𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𡐮.n)))
     𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𐪕.info("Script ends here")
    def 𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆܪ():
     𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆﯜ(𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𑆉[1:])
    if __name__=="__main__":
     𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆܪ()
    # Created by pyminifier (https://github.com/liftoff/pyminifier)