[TIMOB-14740] Android: Automatically generate ProGuard configuration file
GitHub Issue | n/a |
Type | New Feature |
Priority | High |
Status | Open |
Resolution | Unresolved |
Affected Version/s | Release 3.1.0 |
Fix Version/s | n/a |
Components | Android, CLI |
Labels | exalture, notable |
Reporter | Soumya Kanti Kar |
Assignee | Joshua Quick |
Created | 2013-07-31T10:49:01.000+0000 |
Updated | 2019-11-07T00:40:12.000+0000 |
Description
Hi,
Create a sample Android module and build it. Then follow this step by step.
1. Extract the contents of the zip file inside the dist folder.
2. Extract the JAR file obtained from the zip file.
3. Use JAD (Decompile tool) to decompile the any *.class file.
You will observe that the entire source code is displayed. There is no obfuscation. I think Appcelerator must provide an obfuscation procedure during the build process.
If any such process is present (using ProGuard for example), then can you please let us know. If no such process exists then it will be a great idea to add this feature. This will increase the security and also reduce the module size.
Attachments
ProGuard can be used on the JAR that is created after building the Android module. We need to extract the JAR from the modile ZIP. Use ProGuard on the JAR keeping the classes that extend KrollModule and TiViewProxy. Repack the ZIP file. Then use the modified ZIP file in Appcelerator projects.
What's the immediate danger in allowing the .class files to be decompiled. They can just go to https://github.com/appcelerator/titanium_mobile and see the source with comments!
Note that you can use obfuscation now. This is a ticket to automatically generate the ProGuard file.
Note, here is a sample ProGuard file for Titanium. This may need to be updated to fit your usage (especially the file paths)!
To use the ProGuard file: 1. Put a file called "proguard.cfg" in the project/platform/android directory 2. Create a CLI hook that ties into the pre-compile hook and sets builder.proguard to true.
Note, to configure for Crittercism: http://docs.crittercism.com/android/android.html#configuring-proguard-symbolication
It would b worth figuring out what a proper manually-generated ProGuard file looks like these days, and the algorithm for creating one.
I have attached a sample app that has Proguard enabled with the 3.4 SDK. It has a hacked together proguard.cfg file that probably needs some fixing, but the app and the plugin work. I will attach separately the Proguard plugin that is used in the app.
Here is the plugin required to manually enabled proguard. To enable, follow these steps: 1. Create plugins folder if one does not already exist 2. Add the attached plugin com.proguard.android to the plugins directory 3. Enable the plugin in tiapp.xml by adding
4. Add the ‘proguard.cfg' file in platform/android/ directory
Alan, thank you. I'll try to get it put into an app tomorrow for testing.
I had to modify it all a bit. used -outjar to generated an intermediate jar that was reduced, then modify my proguard config to use it and not the regular jars and my apk was smaller. Ended up being faster at times, using google-play-services.jar for example, to use JarJar links to just clean that jar of unused methods before building and just skipping proguard. With libraries such as AWS, the proguard.cfg takes so long to setup and begin to declaring the used methods that its just a lot of wasted time. (no, the AWS recommended proguard.cfg does not work correctly out of the repo)
[~hpham] [~cbarber] thoughts?
I've been trying to get this working. As mentioned before, the plugin and sample attached here do run ProGuard but do nothing with the output. Like Stephen I used -outjars to specify an output directory but I'm not sure how to make dexer pick up the processed folder instead of the original classes folder.
After many trial and error I finally got it working. I added 2 more event listeners to the plugin that move the classes folder to a temporary folder, proguard will then write to the classes directory so dexer can pick up the right files. I would attach the updated plugin and the proguard configuration I'm using but it seems I am unable to.
[~thomascolliers] can you elaborate what did you have add to the event listeners? Probably post a dropbox link of plugin?
Here's the plugin code I'm using to switch out the Proguard output with the unobfuscated output so dexer can pick it up: (Linux/OSX only) https://paste.ee/p/8Y7tG
Like [~jquick] and [~cbarber] mentioned, running ProGuard on a Titanium project will offer little to no benefit. The ProGuard config file provided seems to whitelist all of our Titanium namespaces which means they won't be optimised and obfuscated. Nor can they be, due to Titaniums use of reflection. The only benefit to running ProGuard would be in optimising the use of third-party libraries, reducing final APK size. ProGuard is marketed as a "source optimizer" and not a security measure (for that they suggest DexGuard). So if optimising is the priority, maybe [ReDex](https://github.com/facebook/redex) would be worth looking into? Since it will work regardless of our reflection requirements.
[~gmathews] I understand that the proxies cannot be obfuscated but shouldn't any internal classes be able to be obfuscated? This allows for any more sensitive operation to be moved into a plain old Java class. Without some form of obfuscation this will be a high / medium finding on any enterprise security review.
[~ben.bahrenburg@gmail.com], Titanium and its modules are open source. So, obfuscating the code doesn't make a lot of sense (you can freely see the code on github). Just like how Google doesn't bother obfuscating their own open source Android libraries such as their support libraries. Plus, there is no 100% full-proof/future-proof automated way of obfuscating the code without issues since 3rd party code is out of our control and obfuscation would break their usage of reflection too... or features which use reflection indirectly such as via Java Serialization, GSON, HyperLoop, or possibly other means. If you're worried about code being tampered with (ie: your APK decompiled, code changed, re-compiled, and re-signed), then I think a better solution would be "tamper detection". This is what code signing is for. So, I think what you're really after here is the ability to check on startup that your APK is signed with the signature you originally signed it with. What do you think?
[~jquick] I 100% agree with your statement for commercial apps. The trouble happens when you enter the enterprise space. The approach you mention, ie don't obfuscate, doesn't match the OWASP guidelines, which govern most of the industry https://www.owasp.org/index.php/OWASP_Mobile_Security_Testing_Guide If this was native, the developer would need to determine the best proguard settings to cover both the app and their dependencies. I would recommend that we allow for the same opportunity for Ti. This does a few things. First allows your enterprise customers the flexibility in a "safe space" to be able show they are meeting the OWASP requirement. Secondly it allows the non proxy objects in the Ti framework or modules to be obfuscate. This allows for the ecosystem to more easily create the "tamper detection" methods you mentioned. Please note I've implemented the OWASP tamper detection methods within Titanium. I'm happy to discuss how these could be contributed back to the community.
[~ben.bahrenburg@gmail.com], probably the simplest solution would be to set up ProGuard to not obfuscate anything using a Java @Kroll annotation. That would likely cover most of the reflection issues between JavaScript and Java in Titanium. That and any classes referenced in the AndroidManifest.xml would have to be on the list too. But from there, I think it would have to be the app developer's responsibility to disable obfuscation for any other APIs reflected upon via 3rd party code or by the app developer via HyperLoop. That's where I think we can't provide a 100% full-proof solution. But that said, it's not any better for a native developer using Android Studio either. Hmm...
Thanks [~jquick] . I think this would give the Ti developers the same footing, if not better (given JS encryption) than native developers. Is there anything that I can help with implementing or testing? Additionally happy to contribute the tamper methods if that would be helpful to core or AppC.
Hello all, due to the volume of items and the schedule for 7.0.0 and the technological challenge for this feature, this ticket will be moved to 7.1.0.
Would really love to see this soon. Without this apps with multiple dex files are getting created which is totally incompatible with Android 4.X.X
[~fahad86], in the upcoming Titanium 7.0.2 release, multidex'ed apps will be able to run on Android 4.x (see [TIMOB-25597]). ProGuard is not required. It'll just work.
@Joshua Quick :D happy for this. Thank you very much.