Given the fact that Ruby has powerful reflection techniques, many parts of an extension written in Ruby are readily available to a potential attacker willing to reverse-engineer the code and / or bypass certain licensing mechanisms. It’s easy to list all namespaces, find the name of classes / functions and then attempting to call them, while also enabling live tracing to inspect the names and values of local variables. This also works for signed and encrypted extensions, which I was quite surprised to see when testing on my own extension.
As a result, the Extension Warehouse should give us the option to obfuscate the entire code prior to encrypting it. The current system only deters non-experienced individuals from trying to mess with an extension (as they only see garbage in the encrypted files), however, the Ruby Console opens up many more possibilities. Even though obfuscation is not completely foolproof against a determined attacker, it should help discourage bad actors nonetheless.
Questions: Is anyone already obfuscating their Ruby extensions? If so, are you doing it yourself via a custom script or do you leverage any existing open-source library?
The obfuscation should simply map every symbol to something unreadable, like class LicenseChecker could be turned into class J_2dp3nMxZY_8KbV or whatever. The same should happen for functions and local variables, so the syntax will still comply with Ruby’s grammar and run successfully. The obfuscator just needs to parse the abstract syntax tree and replace the symbols in every scope with something unique (perhaps even using the current timestamp as a seed to randomize the replacement strings).
I’ve read about one such case on these forums where the developer mentioned that his plugin was accessed from some Chinese IP addresses. On top of that, their plugin was being sold on the Asian market using a slightly different name, so “bad actors” do exist.
It just occurred to me that you could write a Ruby script to obfuscate your own code before submitting it for signing and encryption.
You would need to leave the top level namespace module unchanged however. Your obfuscator should ensure that each extension submodule has a unique obfuscated identifier (so that your extensions do not clash with each other.)
But it will certainly make it a lot harder. Someone is more likely to carry out an attack if they can find meaningful class names along the lines of ExtensionLoader, DatabaseAdapter, RemoteFileChecker etc.
Yes, I will probably end up doing just that unless I find an open-source library somewhere.
Let me add this quote from the EW signing page:
We are working hard to help protect your extension. Sign and encrypt your extension to obtain a security certificate.
Hard-working developers deserve better tools in order to keep their intellectual property safe (or as safe as possible). Currently, it doesn’t seem impossible to understand the flow of an extension as set_trace_func lists all the method calls, local variables and their values. Randomizing all these symbols (both class / function names and instance / local variables) will help improve the security of SketchUp plugins.