Skip to content

kalxasath/Sensitive-Data-Guide

Repository files navigation

George Vrynios License Apache 2.0 Platform Android Language Java

Android Studio, how to prevent your Sensitive Data (like API keys) from publishing on GitHub repos

When you use API keys or other sensitive data like username, password, server ip, etc. in your applications, you should take care to keep them secure and ensure that your code does not contain any API keys or any other sensitive information before you make your code publicly available. If you forget to remove them from the code, the sensitive information can be accidentally exposed to a public GitHub repo.

In my project, I had to deal with the removing of the API key from my code every time I wanted to upload my project to the public GitHub repo. As you can figure out this was not the best practice.

After reading a bit more about gradle, I used one of its capabilities to inject Constant Fields and String Resources into my Android Project. As thus, I have decided to write down the steps I just went through in showing someone how to prevent his sensitive data to be published on GitHub repos.

Instead of embedding that information in your application’s code, you can store them in a file in the project’s root folder, and don’t forget to add the filename of this file, in the file .gitigore, so that this file will not be uploaded on the GitHub repo.

If you decide to add contributors to your GitHub repo, then it is very easy for each of them to add an external file to have its own sensitive data stored locally in his project folder.

In this project, you will see how to implement and include such a sensitive data file in your android application, exclude this file from being uploaded in the GitHub repo, and allow to your contributors have permanently their own files. As a bonus, your project can be reviewed easy and fast by letting the reviewer add his own sensitive data directly in your code and evaluate your app as fast as possible, without to deal with an external file.

Step 1 - creating the sensitive_data.txt file

In the project’s root folder of your android application create a file with the filename sensitive_data.txt , inside of this file you can store as many properties as you need in the form of a key-value pair like the example below:

theMovieDbApiKey = “54215e8745_YOUR_API_KEY_56987gh7”
facebookAppId = “6_YOUR_APP_ID_8”
gmailCredentialUsername = “yourmail@gmail.com”
gmailCredentialPassword = “kozd_YOUR_PWD_vf”

Step 2 - Update the .gitignore file - VERY IMPORTANT!!!

Don't forget about to update the .gitignore file, otherwise your sensitive_data.txt file will be published the next time you commit to GitHub repo. To update the .gitignore file just add two lines with the following text:

#my sensitive data
sensitive_data.txt

a comple .gitignore file from this project can be downloaded from here

Step 3 - Reading the key-value pairs from your sensitive_data.txt file

In step 3 & 4, you will use the capabilities from gradle to read the key-value pairs from the file and inject those key-value pairs into your application as a Constant Field and as a String Resource.

Open the Android Studio, on your project from the section “Gradle Scripts” open the file gradle.build (Module: app), after the line apply plugin: ‘com.android.application’ write the code to read the key-value pair properties from the sensitive_data.txt file.

apply plugin: 'com.android.application'

// Begin of reading the sensitive data
// GV 21/02/2018
def noKeyFound = '"NO_KEY_FOUND"'
def theMovieDbApiKey = noKeyFound
def facebookAppId = noKeyFound
def gmailCredentialUsername = noKeyFound
def gmailCredentialPassword = noKeyFound

def sensitiveDataFile = file('../sensitive_data.txt')
def Properties sensitiveData = new Properties()

if (sensitiveDataFile.canRead()){
    // Read the sensitive data from file sensitive_data.txt
    sensitiveData.load(new FileInputStream(sensitiveDataFile))

    if (sensitiveData != null) {
        if (sensitiveData.containsKey('theMovieDbApiKey')) {
            theMovieDbApiKey = sensitiveData['theMovieDbApiKey']
        }
        if (sensitiveData.containsKey('facebookAppId')) {
            facebookAppId = sensitiveData['facebookAppId'] 
        }
        if (sensitiveData.containsKey('gmailCredentialUsername')) {
            gmailCredentialUsername =
                    sensitiveData['gmailCredentialUsername']
        }
        if (sensitiveData.containsKey('gmailCredentialPassword')) {
            gmailCredentialPassword =
                    sensitiveData['gmailCredentialPassword']
        }
    }
}

// In this section a reviewer can insert directly his own 
// sensitive data by replacing the strings beginning with REVIEWERS_
// Just double click on the string and paste you own data
if (theMovieDbApiKey == noKeyFound) {
    theMovieDbApiKey = '"REVIEWERS_THEMOVIEDB_API_KEY_GOES_HERE"'
}
if (facebookAppId == noKeyFound) {
    facebookAppId = '"REVIEWERS_FACEBOOK_APP_ID_GOES_HERE"'
}
if (gmailCredentialUsername == noKeyFound) {
    gmailCredentialUsername =
            '"REVIEWERS_GMAIL_CREDENTIAL_USERNAME_GOES_HERE"'
}
if (gmailCredentialPassword == noKeyFound) {
    gmailCredentialPassword =
            '"REVIEWERS_GMAIL_CREDENTIAL_PASSWORD_GOES_HERE"'
}
// End of reading the sensitive data

android {
    ...

Hint: The reviewer can insert his sensitive data directly by replacing the strings beginning with REVIEWERS_ in the reviewer's section.

Step 4 - Inject those values into your Android project

In the same file gradle.build (Module: app), inside of defaultConfig, the best practice is to add both variants, a Constant Field and a String Resource for the same key-value pair.

android {
    defaultConfig {
        ...
        // Add the commands to inject your Constant Fields 
        // and the String Resources here
    }
}        

Example, for the key-value pair “theMovieDbApiKey” add a Constant Field with the name “THEMOVIEDB_API_KEY” and a String Resource with the same name

// add a Constant Field
buildConfigField "String", "THEMOVIEDB_API_KEY", theMovieDbApiKey

// add a Resource String for the same key-value pair
resValue "string", "THEMOVIEDB_API_KEY", theMovieDbApiKey

All the Constant fields are stored as fields in a gradle generated BuildConfig class, the file BuildConfig.java should not be edited directly!

All the String Resources are stored in a gradle generated file, the file generated.xml should not be edited directly!


Using your sensitive data via Constant Fields or String Resources anywhere in your Java code, layout, AndroidManifest, etc.

// using the Constant field
// in the Java Code
theMovieDdOrgApiKeyC.setText(BuildConfig.THEMOVIEDB_API_KEY);

// using the String Resource
// in the Java Code
theMovieDdOrgApiKeyS.setText(getString(R.string.THEMOVIEDB_API_KEY));

// in the XML layout
android:text="@string/THEMOVIEDB_API_KEY"

// in the AndroidManifest
<meta-data
    android:name="THEMOVIEDB_API_KEY"          
    android:value="@string/THEMOVIEDB_API_KEY"/>

After cloning the repository, open the project in your Android Studio and execute the menu "Tools -> Android -> Sync Project With Gradle Files"


Lastupdate

Written with StackEdit.

About

Android Studio, how to prevent your Sensitive Data (like API keys) from publishing on GitHub repos

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy