Mark Murphy makes a good case on his blog what kind of information should be kept out of public repositories. Key material, e.g. OAuth keys or API keys to various services, are a prime example for this.
The application in question would be a mobile android app, so someone decompiling it to get at the secret keys is not in scope of this question.
How would a build job on a public CI instance, for example cloudbees, be configured so the secret is not leaked in the build log or the compile directory? My main intent is demonstrating the architecture and build process of an app with OAuth-based authentication without disseminating my private keys all over the internet. Therefore, the need for a public code repository and a publicly visible build server.
Currently, I am using maven filtering and placeholders in my java code to create static constant classes but those classes are always visible in the target directory. A post-build cleanup of target still leaves a short time slot in which the resulting java file is visible to the world.
From your description it sounds like you are talking about a key which should not be in the SCM repository, yet needs to be included in the final application. Presumably the application binary is not freely downloadable as such, or else anyway could open it up and get your key, but this is fine if the build result is simply being deployed to some server.
In such a case there is not necessarily any problem in having the key present in the target directory (i.e. Jenkins workspace), or indeed in build artifacts (e.g. lastSuccessfulBuild/artifact/target/myapp.war), so long as these things are not publicly readable. In the case of a CloudBees DEV#cloud Jenkins instance, you can use role-based access control to allow the public to see the changelog for your project, and perhaps the build logs (after vetting them to make sure secrets are not printed), but deny access to the workspace and artifacts.
(As far as artifact read permission is concerned, it seems that this is granted to anyone with overall read permission unless Jenkins is run with -Dhudson.security.ArtifactsPermission=true which is not an option for hosted Jenkins. Probably a plugin needs to be created which enables this permission, and probably also “workspace wipe-out” permission, akin to the existing Extended Read Permission plugin. Workspace browse permission is a standard part of Jenkins at least, which would suffice if you are not archiving artifacts but deploying directly at the end of a successful build.)
This is a problem even if you'r not using public build servers.
Think of it: If the key is in the final package, everyone can see it. No matter at what step of the build it got there, it's public. Anyone can download the package (JAR, APK, etc), explode it, decompile the .class and see the key. It's easy to do it all.
In CloudBees you can put this kind of information in an enviroment variable. See this link:
http://developer.cloudbees.com/bin/view/RUN/Configuration+Parameters .
I don't know much about CloudBees, but I think all public servers have this kind of option, putting sensitive information somewhere that is not public.
Related
I would like to determine which third-party SDKs (like Mixpanel, Google Analytics, Facebook SDKs) are being used in an app, if any. Is there a way to find this out?
Assume for the purposes of this question that I am not the developer of the app, and therefore I don't have access to the source code.
You can use a service like Appbrain to find that out. It's free for the first few lookups.
It's not possible to reliably enumerate the libraries used by an application, for a few reasons.
The main reason is obfuscation: If a user turns on Proguard or R8, they will rename the library's classes, potentially in such a way as to make them unrecognizable.
Another reason is that there's simply not a comprehensive list of every Android library in existence, or a mapping of class names to libraries.
However, if you did want to try to do this, you'd want to retrieve the application's class files and then hunt through them for the start of package names from libraries you care about (as obfuscators are less likely to rename the entirety package names, though they still might). For example, if you wanted to see if an application uses okhttp3, you'd look to see if there are is an okhttp/okhttp3 folder (for the package okhttp.okhttp3).
You could maybe even automate this by finding a list of popular Maven/Gradle packages, downloading them, extracting the class names, and using that as your dataset.
i am using ndk and android studio to secure my api-key and it works now.
also i am trying dirty code to harden disassembling... .
but i can still decompile and see native methods in java classes.
also pre-built .so(shared object) files are available in apk and wil be used again!
Questions:
After releasing the apk, all hackers can see .so file and they can use custom settings in .mk file and program specific native methods like my class for extracting the api-key only. they call my functions related to api-key without knowing the implementation. am i eliminating something here?
is proguard necessary for this way ?
That's right, there is no way to prevent .so reuse by malicious agent. Therefore, your native API should never reveal secret information to the Java side. You can perform some validation in your native methods to check if the calling Java actually belongs to the legitimate APK.
On the other hand, don't underestimate another vulnerability of native code: your .so can be disassembled with relevant tools, and any protection may be torn off. There exist means of obfuscation and resilience to reverse engineering for native code, but the earning curve for them is much steeper than with ProGuard.
Still, it's worthwhile to at least not keep the api-key in plain text in your C++ code. Try yourself to run
strings libnative.so
(here libnative.so is the .so file extracted from your APK) and you may discover important information that is waiting to be stolen from your library, no sophisticated reverse engineering necessary.
As far as ProGuard is concerned, it does not add protection to the native methods you use. You cannot even obfuscate the class name and method name for a native method. (Well, it is possible, but very tricky, and there are no tools that can help with such setup).
You increase the time hackers will need to decompile and understand the .so file. Estimate how hard it is, and change the way your api authentification works from time to time. Doing so makes previous hacking attempt obsolete, even if they have been successful.
To clarify : put the api-key and the authentification process in the native methods. For instance, for an HTTPS api, send the uri, json content, usertoken, to a native method. Then in the native code, use these and the api-key and some hash functions to create a hash. And output that hash to the Java code to be send in the HTTP request. By doing so, it will be hard to guess the authentification recipe by simply monitoring entries and output. Attackers will have to decompile the native code.
Activate Proguard, compile, decompile, and see for yourself. On my opinion it does raise a good level of complexity for a very easy set up.
We have created a gradle plugin to hide keys in the Android NDK, you can check all the implementation on github : https://github.com/klaxit/hidden-secrets-gradle-plugin
The goal is to make it as hard as possible to reverse engineer keys. We encourage to add a custom encrypt algorithm then keys are stored in the NDK as hexadecimal arrays.
We would love to have feedbacks on our solution !
As the title says, I need to create a simulated Android environment within my app. I need to be able to install applications on this environment without installing them on the device.
I know it's possible because this app does it.
I've been searching for a while and I know the app does it by creating an Android environment, but I don't seem to find a lead on how to do it.
EDIT:
I found another app that can do it
Parallel Space
It depends to what degree you need to run the app and what constitutes "installing" the app. Keep in mind that an .apk file is just a java .jar file with some extra data tucked away in various places.
In order to run portions of an Android application without installing it, you will need to
Open and parse the apk. This APKParser class might be a good place to start.
Request any permissions which the app in question requires which aren't already requested by your app. In older versions of Android you would just have to request all possible permissions to start with, but with newer versions you can requestPermissions to make the actual permission request dialog when convenient.
Copy the classes.dex from the application into your data folder. If it uses any common classes which you also use, you'll probably want to nuke these out of the dex file so that you don't have class loading conflict, or else be very, very careful with class loaders.
Load the dex file with a DexFileLoader.
At this point you can load just about any code in the apk, but you won't be able to do a straight load of the Activities, since they're not defined in your AndroidManifest.xml. Instead, you'll need to create a "facade" Activity that hosts the actual activity in reflection and wires up things like the context into the reflected Activity.
These steps should probably work to run at least simple apps without installing them.
Build one yourself!
Android is built on Kernal, so does a Linux
Here is a link to a working project on github which works fantastic in a Linux environment
Here is the documentation on how it is built!
Presently i am a newbie in android development .. I need to develop a secured android application so that i can save it from getteg pirated.
For security of application i have used RMS in J2ME.In J2ME i use to do following steps :
generate a serial number(some random number)
save that number in rms,on next launch of application display the
same serial number on screen and ask user to input valid activation
code then if user enters correct activation code then application
activates and flag is set to true and i save this flag value in
other rms
if flag value is true then home screen is displayed to user on
launching app again else activation page is displayed.
I want to implement this concept in android ..Please guide me how to do it.Or tell me if any body knows some better way for doing this in android.
Secondly I want to obfuscate the apk file before releasing the application..after goggling for 2 days i found that it can be done using proguard.But i am not getting how to obfuscate the code.Please guide and help me for sorting both issues.
Thanks
There isn't really a way to protect any sort of client-side code, whether it is an Android *.apk, a Java *.jar file, or a bit of JavaScript code that runs in your user's browser. The best way to protect yourself from piracy is to make the application dependent on some server-side computation that you provide.
Since you are using RMS, it sounds like you already require a server-side computation. Rather than bothering users to enter an activation code, why don't you associate this activation code with the user's email address when they purchase the application, and then why don't you use OAuth with their Google Account to verify that the user has an email address that is known to have purchased the application?
About RMS
Michael Aaron Safyan said everything, nothing to add.
About ProGuard
ProGuard is now integrated to the Android framework, and requires basically no work to be set up. You just have to enable it as explained in this article and if needed to customize its configuration. "If needed", as the default configuration is suitable for most of the projects. You just have to be careful with the use if the reflexion as most of the packages, classes and methods are going to be renamed by the obfuscation process.
The parallel to RMS in Android is SharedPreferences.
However, the sharedPreferences xml file is not as protected as the RMS files in J2ME (at least in some devices). Anyone with a rooted device can read and write this file easily...
Therefore, I suggest you read about Android's Application Licensing. It's far from perfect, but it's a built in feature you can integrate easily.
http://developer.android.com/guide/publishing/licensing.html
EDIT:
Obfuscation:
To obfuscate your project all you have to do is add proguard.config=proguard.cfg to your default.properties file.
The obfuscation will occur according to the configuration stated in the defult proguard.cfg file.
Note that your code will only be obfuscated when you build the final APK (Android Tools -> Export ...) and I recommend testing the final APK after obfuscation, especially when 3rd party libs are part of the build process
I'm producing an application for multiple clients. Each of these apps only slightly differs (in the ui presentation) from the others and almost all of the other code is identical.
In the best case scenario I would brand something like a boot-strap app for each client so they could have their logo on a separate app in the market. Once a user installed a client's app it would download the core functionality, set some prefs and launch as if it had come from a single download. This way I could get the benefit of updating for bug fixes once rather than for each application (slated for 20-30 by end of year.) I've read that this isn't possible because of security measures though (and additional visits to the market place for the second download or having to allow installation from unknown sources isn't acceptable.)
I'm thinking that worst-case/only-case might be to include this shared code in each application and create some batch build and deploy once updates are ready.
I'm looking for a .dll like approach for economy of effort and safety.
I'd appreciate any input on this.
Thanks!
The java equivalent of a dll is a jar file. You can extract all of your shared functionality into a library project that compiles into a jar and then include that as a library in your other projects.