Let’s say, there’s a server I have access to and which belongs to a customer. I’ve set up and launched a Phoenix app on it.
Because of our agreement with a customer, I’m not obliged to provide the source code of an app. The only thing I have to do is to lauch it end ensure that it works. Besides, I have a reason to try to protect the source code.
Question: how could I a) protect, or b) make it more difficult to get access to
the source code of said application?
More concretely:
1.1) Is there a way to distribute an app in the compiled form only?
I know how to build a release manually, and I’ve done it. However, there’re so many files there in it, and I don’t know which ones are essential for an app to run, and which aren’t.
1.2) Is there a way to also obfuscate the source code? Whether it be before, during or after compilation.
I’m aware that the maximum I could do is to make it more difficult to access the source code, or understand it. rather than protect it completely. And this is fine.
P.S. My local OS-es and the one on a server are identical. Therefore, I can compile a release locally. And I can set up all the env. locally as well.
There are tools to decompile the beam files. There are several threads around asking this same question which you might want to check out. Short answer is: no.
Could you restrict access to the location of the files somehow?
That’s fine because a compiled version only on customer’s server will always be better than source code anyway. A customer may not be that tech-savvy to decompile it.
So – is it possible to have a compiled version only on a server to run an app?
Technical solutions can only put minor obstacles in the way. The correct tool for this is called “contract law”, and it doesn’t involve any software changes.
If you’re still interested in putting the obstacles in, it would be useful to think through exactly what you’re aiming to prevent. For instance, just writing really poorly-structured code with confusing function names would prevent anybody from understanding but that probably isn’t what you want
If I understand you correctly you don’t want a perfect solution, but just something that makes your source code opaque to someone with no technical background.
Maybe the following project will interrest you then.
Technical solutions can only put minor obstacles in the way. The correct tool for this is called “contract law”, and it doesn’t involve any software changes.
Anecdotally (I don’t have a source to back this up, I just heard it from an old coworker), Github’s on-prem enterprise employs this solution. They strcitly monitor ssh access to the box that runs GHE, and you’ll get an angry phone call wanting to know why you SSH’d in if you do so for an unknown reason. Their stuff is all Ruby, so I have to imagine the same reasoning is at play here.
@tirana, please be considerate towards those taking time out of their busy day to contribute to a thread you’ve posted. If somebody replies with something that wasn’t quite what you were looking for you can just ignore it - it’s quite possible that that same piece of information might help someone else reading the thread in future. Please keep in mind we are a nice friendly community here
This leads me to think Elixir is your first compiled language. Use a release, and there will be no source code, just .beam files. Yes, they’re vulnerable to disassembly, but it is some sort of barrier.
A release doesn’t have source code. mix release compiles the code and transfers it to the release folder. Pretty much all the files bundled into the release folder are required for it to run. The release task goes to some effort to remove unnecessary stuff. From the docs on “why releases?” (mix release — Mix v1.14.2):
Self-contained. A release does not require the source code to be included in your production artifacts. All of the code is precompiled and packaged. Releases do not even require Erlang or Elixir in your servers, as it includes the Erlang VM and its runtime by default. Furthermore, both Erlang and Elixir standard libraries are stripped to bring only the parts you are actually using.
The main downsides of building and shipping releases that I’ve experienced are:
You have to build on the same architecture that you are distributing to.
If the contents of runtime.exs are different for each installation (highly likely) you need to remember to apply them again after each update, or (better) use environment variables for the settings.
The compiled code can be decompiled, but this requires some know-how and effort.
1.1) mix release does that. Note that bundled in a release is the VM itself (:include_erts option defaults to true), this is probably contributing to the ‘so many files’ you see. As mentioned above there should be no source/docs in there, but I’m not an expert on releases.
1.2) I’m not aware of any Elixir obfuscation software, but at a minimum debugging symbols are already stripped from the release (:strip_beams option defaults to true) which may help make decompiled code less readable.
As mentioned above, if you packaged up a release in bakeware/burrito, that would increase the barrier… but if the customer is going to go as far as understanding decompiled BEAM, then something equivalent to an app.tar.gz isn’t going to provide much challenge.
Firefly (formerly known as Lumen), gives developers an alternative compiler to the BEAM. It allows developers to capitalize on Elixir’s inherent distributed systems capabilities and offers new levels of efficiency and speed for compiling Elixir applications.