I want to check and allow the use of my app just if it has been downloaded from the Play store, and it has not been shared by other user or from any other source. How can I prevent an user to use the app if it has not been downloaded from the Google Play store?
This method will check if your app has been installed from the Play Store.
boolean verifyInstallerId(Context context) {
// A list with valid installers package name
List<String> validInstallers = new ArrayList<>(Arrays.asList("com.android.vending", "com.google.android.feedback"));
// The package name of the app that has installed your app
final String installer = context.getPackageManager().getInstallerPackageName(context.getPackageName());
// true if your app has been downloaded from Play Store
return installer != null && validInstallers.contains(installer);
}
Some days ago I released an Android library, PiracyChecker, that protects your app using some techniques, such as Google Play Licensing (LVL), APK signature protection and installer ID (this one).
Bypass the Check
I want to check and allow the use of my app just if it has been downloaded from the Play store, and it has not been shared by other user or from any other source.
While this check is possible to achieve programmatically its also possible to bypass by repackaging the app without the check or by using an instrumentation framework at runtime to bypass the check. An example of such a framework is Frida:
Inject your own scripts into black box processes. Hook any function, spy on crypto APIs or trace private application code, no source code needed. Edit, hit save, and instantly see the results. All without compilation steps or program restarts.
I wrote an article to show how to use Frida to bypass certificate pinning in an Android app, and the same approach can be used to bypass this check. The only difference is that you need to find the correct Frida script or write yourself one and use it in place of the on to bypass pinning. The Frida Code Share website as a huge set of scripts and one may exist for this propose or can be used as a starting point to see how to write your own script.
Protect the Check
How can I prevent an user to use the app if it has not been downloaded from the Google Play store?
So, if you use the built-in context.getPackageManager().getInstallerPackageName(context.getPackageName()); or any other method you will be safeguarded against normal users that do not install your mobile app from the Google play store, but anyone wanting to attack your mobile app will have several ways of bypassing this protection as I mention above.
A possible to solution to protect your mobile app against attackers bypassing your check is to use Runtime Self Defense Protections or a Mobile App Attestion solution, and I recommend you to read this answer, especially the sections Hardening and Shielding the Mobile App, Securing the API Server and A Possible Better Solution to see how you can prevent your mobile app to work properly when its not your genuine mobile app.
Do You Want To Go The Extra Mile?
In any response to a security question I always like to reference the excellent work from the OWASP foundation.
For Mobile Apps
OWASP Mobile Security Project - Top 10 risks
The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.
OWASP - Mobile Security Testing Guide:
The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.
com.android.vending is the play store package name,
context.packageManager.getInstallerPackageName(context.packageName) gets you the source package name.
Other source such as Huawei App Gallery to download the app. But i am not sure what its package name
Just for completeness: client-server applications (apps communicating with your own server) should use Server-Side License Verification to check that the app was installed from GP and is valid - License Verification Library (LVL) will be responsible for this.
This can be used to protect backend servers from not legitimate clients, such as bots, which will have to pass LVL verification first, before getting access to other backend functionality.
Related
I want to check and allow the use of my app just if it has been downloaded from the Play store, and it has not been shared by other user or from any other source. How can I prevent an user to use the app if it has not been downloaded from the Google Play store?
This method will check if your app has been installed from the Play Store.
boolean verifyInstallerId(Context context) {
// A list with valid installers package name
List<String> validInstallers = new ArrayList<>(Arrays.asList("com.android.vending", "com.google.android.feedback"));
// The package name of the app that has installed your app
final String installer = context.getPackageManager().getInstallerPackageName(context.getPackageName());
// true if your app has been downloaded from Play Store
return installer != null && validInstallers.contains(installer);
}
Some days ago I released an Android library, PiracyChecker, that protects your app using some techniques, such as Google Play Licensing (LVL), APK signature protection and installer ID (this one).
Bypass the Check
I want to check and allow the use of my app just if it has been downloaded from the Play store, and it has not been shared by other user or from any other source.
While this check is possible to achieve programmatically its also possible to bypass by repackaging the app without the check or by using an instrumentation framework at runtime to bypass the check. An example of such a framework is Frida:
Inject your own scripts into black box processes. Hook any function, spy on crypto APIs or trace private application code, no source code needed. Edit, hit save, and instantly see the results. All without compilation steps or program restarts.
I wrote an article to show how to use Frida to bypass certificate pinning in an Android app, and the same approach can be used to bypass this check. The only difference is that you need to find the correct Frida script or write yourself one and use it in place of the on to bypass pinning. The Frida Code Share website as a huge set of scripts and one may exist for this propose or can be used as a starting point to see how to write your own script.
Protect the Check
How can I prevent an user to use the app if it has not been downloaded from the Google Play store?
So, if you use the built-in context.getPackageManager().getInstallerPackageName(context.getPackageName()); or any other method you will be safeguarded against normal users that do not install your mobile app from the Google play store, but anyone wanting to attack your mobile app will have several ways of bypassing this protection as I mention above.
A possible to solution to protect your mobile app against attackers bypassing your check is to use Runtime Self Defense Protections or a Mobile App Attestion solution, and I recommend you to read this answer, especially the sections Hardening and Shielding the Mobile App, Securing the API Server and A Possible Better Solution to see how you can prevent your mobile app to work properly when its not your genuine mobile app.
Do You Want To Go The Extra Mile?
In any response to a security question I always like to reference the excellent work from the OWASP foundation.
For Mobile Apps
OWASP Mobile Security Project - Top 10 risks
The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.
OWASP - Mobile Security Testing Guide:
The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.
com.android.vending is the play store package name,
context.packageManager.getInstallerPackageName(context.packageName) gets you the source package name.
Other source such as Huawei App Gallery to download the app. But i am not sure what its package name
Just for completeness: client-server applications (apps communicating with your own server) should use Server-Side License Verification to check that the app was installed from GP and is valid - License Verification Library (LVL) will be responsible for this.
This can be used to protect backend servers from not legitimate clients, such as bots, which will have to pass LVL verification first, before getting access to other backend functionality.
I work for a business that provides an Android app to multiple clients.
Each client uses their own EMM (Enterprise Mobility Management) solution.
I am attempting to ascertain what the options are for remotely configuring our app on Android devices using EMMs.
The configuration I need to deliver is an 820 character string containing a license key.
Not every device will require this license key, so will need to be set on a per device level.
The current method we use to deliver configuration to our app is to transfer a file to the device containing the configuration details.
This method works OK except: it’s a bit primitive; and one of our client's EMMs does not provide this functionality.
I understand that Google provides Google Managed Account and Managed Google Play Accounts API’s that can be used to configure devices.
We have ruled out Google Managed Account as an option because it requires the client to sign up to G-Suite which carries quite a heavy financial cost, and would be overkill just for being able to deliver a license key.
Managed Google Play Accounts could possibly be an option. It appears to require a one off cost of applying for a developer license of only £20, which is fine. Once the app is uploaded to the client’s private Google Play Store it looks as though it can be managed via the clients EMM UI, as long as it has the correct information in AndroidManifest.xml ( https://developer.android.com/work/managed-configurations ).
The Managed Google Play Account option could, potentially be the least worst option, but again having to introduce a dependency on Google services for a license key feels a but over the top, just not as over the top as using G-Suite.
Is there any other way, apart from the three methods mentioned above, of delivering app configuration to Android devices?
Based on my understanding managing multiple enterprises could be managed using https://developers.google.com/android/management/managed-configurations-iframe
Admin would have permission to manage multiple configuration files and devices on the console. We can also provision a device from the following strategy mentioned here https://developers.google.com/android/management/provision-device
You may also refer this link: https://developers.google.com/android/management/existing-emms for managing existing EMM's.
I have this app developed and issued to users via USB. But I want to prevent them from extract the APK and install it on other phones.
Currently, I have a APK signing signature check when the app launches and prevent it from running if it doesn't match mine. But it doesn't to stop those APK extractor apps, this one for example.
https://play.google.com/store/apps/details?id=com.ext.ui&hl=en
I checked the extracted APK and it has the same signature as my original! Is there any other ways to stop it?
My app is a standalone app so it doesn't have a server to talk to...Thanks!
Disclaimer! There's no way you can protect your app 100% but you can try the following ways:
Google Play Licensing and the License Verification Library (LVL)
This service allows your app query a Google Play Licensing server to determine if currently running device is recorded as a purchaser.
More info
OBFUSCATION
Eliminate all chances of reverse engineering which is a way of generating an apk from your app.
More info
COPY PROTECTION
Although superseded by licensing on some platforms (most notably Android), copy protection is a simple way of fending off more perfunctory attempts at piracy.
Digital rights management (DRM) can be built into the app itself, be part of the app store to which it is uploaded (such as Amazon DRM), or purchased as part of a third-party paid DRM service.
In general you can not prevent your app from being extracted from a device. Furthermore any of your user could simple upload the retrieved APK file somewhere on the net.
Therefore you can only protect your app from being used by "the wrong people". I see two possible solutions for doing so:
Dongle the version to a specific device
You know the principle by many shareware software: After installing the app requires to enter a license code that activates it. The license code is generated by you after receiving some sort of device fingerprint and the app checks if the license is valid for this specific device.
Embed a water-mark that allows you to identify who has leaked the APK
This would require to create unique APK files for each of your legitimate user.
This is the Android version of App for limited or restricted audience
The project
I'm going to start a brand new project for one of our customers that will be deployed to our customer's suppliers to track on-field activity. I am skilled enough on Java/Android development so this question is only about deployment.
Owned vs provided devices
Our customer will either provide a Samsung Galaxy Ace 4 device to the suppliers or will allow the supplier to use their own Android 4 smartphone without warranties from us. Our customer currently has a Google for Business organization set up, but we cannot rely on that (see partial answer).
Technical (non functional) requirements
Ability to easily distribute application and updates across enterprise users.
Application should not be visible to the public
Application must be able to send crash reports so our team can inspect and investigate
The question is
Given the above "should not be visible to the public" statement, what is the most effective and efficient way to deploy an Android app targeted only for enterprise users?
I'll post a partial answer below. I'm asking others to enrich it with other possible means, including using Alpha/beta channels for which I don't have experience about
Currently, limited-audience Android applications can be deployed like this:
Publishing on Google Play as a free app for the public
Maybe adding a limitation to our country
Advantages:
Simplemost and well documented
Auto deployes updates as soon as no new permission is enforced
Collects crash reports on Dashboard
Disadvantages:
Everyone can download the app
This has the disadvantage that some organizations may not be happy as publicly available code might in some cases help exploit vulnerabilites on remote systems (but it is almost impossible if app is well-written and obfuscated)
If country limitation is enforced, imported devices won't download
Distributing the APK direct URL
Advantages:
The app remains private (enterprise users are surely not going to redistribute the app to friends as it's no use without enterprise credentials)
Disadvantages:
No crash reports unless implementing a third-party library
No auto updates unless implemented by custom code or third party library. Implementing auto updates prevents the app from being published to Google Play in the future, even on a private channel, as Play prohibits apps that auto-update themselves via third-party channels. Or, to be precise, the auto-update feature and Play publishing require, in order to exist together, maintaining two APKs
Google Play for Enterprise
As mentioned on this link, Google Play provides a private channel for app deploying for users withing a Google for Business organization. This is the perfect approach for applications that organization's users must use
Advantages:
Same as publishing for the public (simple, auto update, crash report)
Visible only to restricted audience
Disadvantages:
Every device must come with a Google account within the organization, and it will be economically unfeasible to [request the Sysadmin to] enable Google accounts for every external supplier in our target organization
Permanently in Alpha/Beta
I haven't tested this yet, as it is also very tricky. Basically, it involves using testing mode without ever going to production. With Google Play, one can deploy artifacts into Alpha (e.g. test server environment) and Beta (a trick to point to production server environment) without ever moving the app to Google Play's Production stage.
All requires setting up special moderated Google+ groups
Potential advantages:
Same as publishing to enterprise
Disadvantages:
Only telling users to subscribe to Google+ and joining a community
From your requirements, I would suggest distributing the APK via a direct URL and integrating a service such as HockeyApp (see their Android SDK for more) to manage both the crash reports and app updates.
"Ability to easily distribute application and updates across enterprise users"
Many services allow .apk files to be uploaded directly to their service for deployment. A direct download link is then generated for that build.
Crash information is collected and updates are automatically displayed if the app implements the Android SDK provided by the service.
"Application should not be visible to the public"
Services such as HockeyApp do not publicise direct download links publicly. This link can therefore be distributed as required.
"Application must be able to send crash reports so our team can inspect and investigate"
Full stack-trace and device information is sent along with crash reports and can be viewed online by technicians.
From my experience there are a few pros and cons:
Pros:
App distribution is super easy, as simple as visiting a website.
Bug reports are comparable to those received through Google Play
Cons:
Crash report's aren't sent automatically and updates aren't automatic
By default, updates and crashes appear as system dialogs prompting users to either send the crash report/update the app or cancel. Ideally, no user interaction should be required to perform the desired actions. I am sure it is possible but have not found relevant documentation for it.
Cost. These services aren't free.
Would require the removal of the service SDK from the app if uploaded to Play Store
Suppose I have a wifi network with a walled garden that prevents users from accessing Internet unless an authentication procedure is performed via browser.
Suppose I have an application on Google Play that automates this process for inexperienced people. And suppose 95% of users are inexperienced and unwilling to perform SMS-OTP authentication on a site that is not optimized for mobile.
Scenario
A person asks a clerk how to connect to internet using Android. The clerk suggests the person to download the Android app, but the person responds he has no Internet access because he has no 3G data plan.
Possible workaround
The walled garden portal detects the device running Android by user agent and says: "Would you like to download an APK from our internal network without having to go to Google Play?". The user accepts, unlocks unknown sources and installs the app.
Question
In this scenario, if a user downloads an APK of a Google Play-available application, signed with same key, on his device, will the installed application be linked to Play and subject to updates? And I mean without using a Market linker app.
That's my old answer, don't read it, just skip to the edit portion:
Short answer is no!
I'm sure there're geeky ways around to link an app to its Google Play
variant, but your scenario of non-geeky customers I reckon the best
option is to program the network to allow Android mobile access
(checking the user agent) to play.google.com (maybe even from the
redirection website auto-launch the google play link direct to said
app).
edit:
I'm thinking a bit more on this problem and I would like to change my answer to "I don't know" (what a horrible answer). But I would like to propose a test that you can do it yourself.
The reason I'm changing the answer is because I remember now apps like Titanium and they do link the app to the Play whenever restoring a backup. Of course, Titanium needs root, but that's because it's messing with other apps, not its own.
So in light of what I discusse I'll suggest you a simple test:
build an app, anything, Hello world!
Upload this app to Google Play and make it active
Wait a few hours for Google servers to make it available
Manually flash the same build version (with exact same signing key, etc) to a device.
Reboot the device (to be sure the system will read through installed applications and do communication with Google Play)
Go to Google Play on the device and check if it shows the app
It's possible that the app have the same package name and signed with the same key, the Google Play on the device itself will recognise it as the same and link it.