4

Using Play or Grails or any other JVM framework;

Is there a way (or what is the way) to full compile the generated war/jar files so that the source code can be hidden, without the possibility of decompiling?

Or even after compilation, is it possible to easily decompile and get strings and classes? e.g. db connection et al.

Thank you.

Steve Kuo
  • 61,876
  • 75
  • 195
  • 257
Phil
  • 13,875
  • 21
  • 81
  • 126
  • 2
    @mgaert http://meta.stackexchange.com/questions/5280/embrace-the-non-googlers –  Mar 01 '12 at 15:41
  • 1
    Play and Grails are web application frameworks. Decompilation is generally not relevant for them, since end users see only the HTML the code outputs and the only one who has access to the compiled code is the sysadmin who knows the DB connection data anyway... – Michael Borgwardt Mar 01 '12 at 15:45
  • Getting strings out of a binary is about as complicated as getting strings out of a jar - not at all. So you really shouldn't rely on that for sensitive information.. – Voo Mar 01 '12 at 15:54
  • Michael Borgwardt, I am seeking an answer to my question, not for anything else. My concern is stated in the question, clearly. – Phil Mar 01 '12 at 16:19
  • @Voo, I want to protect especially the DB connection strings in case a server hijacking and having the JAR-WAR-code stolen. – Phil Mar 01 '12 at 16:20
  • @Phil *puts on his black hat* Ok, let's for a second assume you can perfectly obfuscate your code so that I really have no chance finding the string itself or understanding what's going on in your code (you can't do either though). A problem? Not at all. After all you're linking to an external jar to get your connection in the first place and conveniently hand over the plain-text string to a well known function there. Now I'm not saying don't use obfuscators, but the very real problem is that they give you wrong sense of security that really isn't warranted. – Voo Mar 01 '12 at 17:05
  • 1
    cont. On a general note: One of the most important things you have to understand about security is really simple: Everything your program has access to, the user has access to as well. Handle everything you send to the user as compromised and well known to the attacker. – Voo Mar 01 '12 at 17:07
  • @Voo, that sounds genius! So, if somebody really wants to get to the DB, after taking over the server, they can use a modified DB driver to extract the connection string and use it anyways? That's genius. So basically, protecting the code won't do much. What security measures would you suggest then that might be even better than investing in obfuscation? – Phil Mar 01 '12 at 19:58

3 Answers3

10

No, you cannot compile anything without the possibility of decompiling. That said, you can do some things to make the process more costly.

The real trick is to make the costs low to you and expensive to others. In short, expect to pay more in time / money / inconvenience and realize that you have just made the challenge harder, in one way (that possibly might become easy to circumvent). But, look on the bright side, the entire software industry has gotten along just fine without absolute protections against decompiling.

Sign and seal your JAR files. This prevents people from adding things to your JAR files and prevents people from replacing parts of your code (to get a better understanding of the operating program).

Consider a class / method name obfuscator. This will rename your classes and method names into an equivalent structure that contains small names like "a.a(..)" instead of "Client.connect(...)". This makes it harder for others to read your code (and others includes yourself in this case, so if you intend to debug, this increases your cost to support the code). Oh, and this breaks any reflection, so you must provide work-arounds and fixes for reflection.

If you provide any kind of decent logging, you also need to obfuscate the logging, otherwise one need only read the log messages emitted from a class to figure out that class "h" is the DatabaseConnection, class "k" is the "User" data object, etc.

Embedded strings in your classes can always be extracted. So, if you want to protect them, you must embed "scrambled" strings, and "descramble" them prior to use. Doing so has a CPU overhead, and as soon as the "descrambling" routing is known, the entire process can be circumvented.

Exotic solutions exist, like rewriting your code into equivalent code which performs similar operations. The problem is that for the end deliverable to be useful, it still must perform identically to the original, yet now to debug the output isn't even following the original code.

Often one wants to protect the ability to solve the problem, not really the source code. Keep this in mind, by delivering something that works, often copying the already-compiled elements is enough to breach the "this code is mine" mindset. If you really want control over you code, don't release it, set up a server and offer the software solution "as a service" on your own hardware.

Edwin Buck
  • 69,361
  • 7
  • 100
  • 138
  • Thank you very much. How would you suggest to protect DB connection strings for SaaS app? – Phil Mar 01 '12 at 16:21
  • Consider carefully what must use the db connection string. Eventually you'll have to transmit it to the database driver, and at that time, odds are excellent that it not being obfuscated is a hard requirement. If you store it on disk, and want to prevent casual browsing, encrypt it, and have the software decrypt it. GPG is a good encryption solution, but encryption comes with risks too. If you lose some of the information (or just loose access to some information) you could irreversibly lose the data too. – Edwin Buck Mar 01 '12 at 16:28
  • Better to configure you database to only accept a particular kind of connection than to keep it accepting all connections and try to "fix" it by making your routine connection less understandable. For example, perhaps you could reject all connections from the wrong "hosts", that are not on "ssl" sockets, that don't authenticate with your special released "key". Not a mathematical certainty that it cannot be circumvented, but it would make it MUCH harder to do so. – Edwin Buck Mar 01 '12 at 16:29
  • If the node where the client code is hosted gets hijacked, someone can create a tiny little custom app using the connection-string and password data extracted from the JAR, to download the DB to the node and then get it from there. Hosts is not a perfect solution in this case. Only a true encryption-compilation would stop it, I assume. But thank you very much for your help. I will nonetheless implement these measurements. You have been very very helpful. Thanks a lot. – Phil Mar 01 '12 at 16:37
  • Yes, which is why investing in some sensible cost defenses _and_ some sensible cost attack monitoring is always a good combination. Glad to help, and you're welcome. – Edwin Buck Mar 01 '12 at 16:50
1

What you looking for is called obfuscation. There are several popular byte code obfuscators for java.

AlexR
  • 114,158
  • 16
  • 130
  • 208
0

Do a quick search for grails or groovy code obfuscators and it should generate a bunch of results. It's fairly easy to decompile afterwards if you know what you're doing. There's no foolproof way.

Matt K
  • 6,620
  • 3
  • 38
  • 60