Detect if an app is installed from Play store
Asked Answered
P

5

50

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?

Pomcroy answered 31/5, 2016 at 7:53 Comment(1)
Possible duplicate of How to know an application is installed from google play or side-load?Valuable
B
69

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).

Brunelleschi answered 31/5, 2016 at 8:4 Comment(4)
Does this still work? I show a popup to my users when they sideload my app and some of them are complaining that they see the popup even though they installed the app through the playstore.Clarethaclaretta
how to detect that app is installed from Huawei store?Mechanical
I still have few users who are reporting this issue. Using same code snap except adding com.google.android.feedback. List of package app shows here shows it has nothing to do with installation. Anyone is in same situation ?Crary
Not quite a robust solution though. See https://mcmap.net/q/261366/-is-it-ok-to-check-legality-of-installing-paid-android-app-by-checking-getinstallerpackagenameMayamayakovski
B
5

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.

Biocatalyst answered 22/6, 2021 at 16:46 Comment(0)
Y
2

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

Youmans answered 23/7, 2019 at 7:17 Comment(1)
For Huawei AppGallery it's: com.huawei.appmarket. You can verify the app via: adb shell pm list packages -i [package name]Fortunna
A
0

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.

Aquinas answered 7/9, 2022 at 10:17 Comment(0)
A
0

This is better answer to directly check users come from playstore or not. But do not block users on this basis because there is many reasons. You can just verify.

So, I add this code in app and checked output in many conditions.

// The package name of the app that has installed your app
final String installer = context.getPackageManager().getInstallerPackageName(context.getPackageName());

Condition 1: I directly install app from Android Studio during Coding(like testing via adb/wire).

Output: null

Condition 2: I build signed apk and install in device

Condition 3: I take backup of signed apk in storage and reInstall it

Output(same): com.google.android.apps.nbu.files

Condition 4: I build signed abb and update on PlayStore

Output: com.android.vending

Condition 5: I take backup of app that installed from playstore in storage and reintall it

Output: com.google.android.apps.nbu.files

..if anyone test output in other conditions like ( output of modded app that download from playstore ) then Please Update answer.

Appling answered 10/11, 2023 at 8:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.