13

Getting error when uploading build in google play store console. The error is following.

Leaked GCP API Keys Your app contains exposed Google Cloud Platform (GCP) API keys.

The culprit code is following.

Places.initialize(getApplicationContext(), BuildConfig.GOOGLE_API_KEY);

According to the documentation i am reading key from BuildConfig and also restrict the key. But still the same issue. how can i fix this issue..

Marcos Echagüe
  • 547
  • 2
  • 8
  • 21
Kamran Omar
  • 1,815
  • 9
  • 31
  • 49
  • 5
    The [manual says](https://support.google.com/faqs/answer/9287711?hl=en) "Please Note: If you have already added restrictions to your API key, you can ignore this warning." But at the same time, it says the warning cannot be ignored. Stupid Google. – Daniel W. Feb 16 '22 at 15:02
  • Have you really done what's on [this page](https://cloud.google.com/api-keys/docs/add-restrictions-api-keys#adding_android_restrictions)? Have you pinned your key to your app? – Daniel W. Feb 16 '22 at 15:06
  • @DanielW. yes i did this. – Kamran Omar Feb 16 '22 at 16:30

3 Answers3

20

I also faced the same problem. I couldn't find any proper solution for this. After lot of searching I found a solution. So I am giving a complete guide for this issue. Many thanks to Prasenjit Banerjee for helping me.

Complete guide for use API Keys and avoid Leaked GCP API Keys security issue in Google Play Console :

  1. First of all you need to follow API security best practices for add restrictions and securely using API keys.

  2. Then follow Set Up an Android Studio Project for add API keys to local.properties and use them in AndroidManifest.xml & Main program.

  3. Finally access API keys As a variable in your AndroidManifest.xml file :

<application>
        .
        .
        .
        .        
        <activity>
            .
            .
            .
            .
        </activity>
  
    <meta-data
        android:name = "keyValue"
        android:value = "${KEY}"/>
      
</application>
  1. Access API keys in MainActivity.kt and type in the below code to get the KEY value from the meta-data in AndroidManifest.xml (Find solution from this article in GeeksforGeeks ) :

    Note: Don't use BuildConfig class to get these API keys because this class expose those properties as variables.
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //get the KEY value from the meta-data in AndroidManifest
        val ai: ApplicationInfo = applicationContext.packageManager
            .getApplicationInfo(applicationContext.packageName, PackageManager.GET_META_DATA)
        val value = ai.metaData["keyValue"]
        val key = value.toString()

        //for testing only
        Toast.makeText(applicationContext, key, Toast.LENGTH_LONG).show()

        // use this key to initialize places sdk
        Places.initialize(applicationContext, key)
    }
}
Milan Maji
  • 363
  • 1
  • 5
  • 9
  • 1
    Very useful, we've been struggling with this message in several updates, thanks Milan! – Jorgesys Jul 13 '22 at 21:01
  • How can we handle different keys for different flavors any recommendation for doing that? – Hamid Javed Nov 25 '22 at 11:23
  • 2
    Can you explain what exactly this achieves? All I see is that you moved the API key from one publicly accessible place to another. Accessing Manifest entries is as trivial as reading BuildConfig variables. – bompf Jan 10 '23 at 10:48
  • This solution is also not safe. Android Manifest meta-data values can potentially be accessed by other apps on the device. – ricardopereira Mar 15 '23 at 11:19
  • Good one. but how can i maintain dev, prod keys – Amal Jun 07 '23 at 01:42
  • 1
    According to the [secrets-gradle-plugin](https://github.com/google/secrets-gradle-plugin) document, you can set build-variant specific properties (build type or flavor), create a properties file at the root directory of the project with the same name as the variant. For example, to set keys specific for the `release` build type, create a new file called `release.properties` containing release-specific keys. @HamidJaved @Amal – Milan Maji Jun 08 '23 at 04:51
1

In order to secure your API Keys in GCP you have to search for "Credentials" in the Cloud Platform Console. Create a new API Key using the Create credentials button, configured the same as the compromised API Key. The restrictions on the API Key must match, otherwise you may suffer an outage.

Push the API Key to all locations in which the old key was in use, and then delete the old key.


I would recommend you to take a look at the official documentation for handing compromised credentials in GCP for a better detail.

Other than that, you might want to consider Keyless API authentication by leveraging workload identify federation

Pepe T.
  • 174
  • 6
1

You are not supposed to get GCP Key from local properties directly from BuildConfig. I fixed it by getting the key from application metadata by using this extension function

fun Context.getKey(): String {
    val applicationInfo = packageManager
        .getApplicationInfo(packageName, PackageManager.GET_META_DATA)
    val keyValue = applicationInfo.metaData?.get("com.google.android.geo.API_KEY")
    return keyValue.toString()
}

So when you want to get the key you can use

  1. Fragment
Places.initialize(getApplicationContext(), requireContext().getKey());
  1. Activity
Places.initialize(getApplicationContext(), this.getKey());