facebook noscript

How to Secure Sensitive Data Sent From Android Apps

September 3, 2018

Wherever there is sensitive data, there is also motivation for malicious third parties to try and steal it. In order to ensure your company's sensitive information never gets leaked, it's essential to take steps for securing it.

Let's consider the scenario of sending sensitive data from an Android mobile device to your API server. How do you make sure that the data is safely received by the server?

By using VGS.

Secure sensitive data from android apps

It's common for sensitive data such as credit card forms, personal data, or user credentials to be uploaded from mobile apps to API servers, but this doesn't guarantee the data is received by the server safely. VGS bridges that gap. Check out the VGS getting started guide to get acquainted with the product and create your first vault.

If you need to secure PII, credit card, or bank account data sent from mobile devices, the VGS inbound routes would look similar to these:

image2

As soon as you're set up, check out your inbound route vault URL. This will be used as a path for your upstream API server to which you send requests.

Now that you are set up in VGS, let's see what using this on Android looks like. Typical Android apps use libraries like Retrofit or OkHttp for making HTTP calls. The code itself wouldn't look much different from regular calls to your API. We'll use httpbin service as our API:


package com.verygoodsecurity.samples.http

import retrofit2.Call
import retrofit2.http.Body
import retrofit2.http.POST

interface HttpbinService {
    @POST("post")
    fun post(@Body data: PiiData): Call<HttpbinResponse<PiiData>>

    @POST("post")
    fun post(@Body data: CardData): Call<HttpbinResponse<CardData>>

    @POST("post")
    fun post(@Body data: BankData): Call<HttpbinResponse<BankData>>
}
        val retrofit = Retrofit.Builder()
                .baseUrl(getString(R.string.vgs_proxy_url))
                .addConverterFactory(GsonConverterFactory.create())
                .build()
        httpbinService = retrofit.create(HttpbinService::class.java)

Here the vgs_proxy_url string would look similar to this:

<string name="vgs_proxy_url">https://tntzklp0qzc.SANDBOX.verygoodproxy.com/</string>

In this case we'll send personal SSN data. We'll use an Android screen layout for entering data:

...

    <EditText
        android:id="@+id/editBankSsn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:inputType="numberSigned"
        android:hint="@string/ssn"
        android:layout_margin="8dp"
        android:maxLength="10"
        app:layout_constraintBottom_toTopOf="@id/btnBankSubmit"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toBottomOf="@id/editBankAccount"/>

    <Button
        android:id="@+id/btnBankSubmit"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/submit"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toTopOf="@id/textBankRedactedData"
        app:layout_constraintBottom_toBottomOf="@id/editBankSsn"/>

    <TextView
        android:id="@+id/textBankRedactedData"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textStyle="bold"
        android:layout_margin="8dp"
        android:textAppearance="@android:style/TextAppearance.Large"
        android:gravity="center"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toTopOf="@id/textBankName"
        app:layout_constraintBottom_toBottomOf="@id/btnBankSubmit"/>

    ...

    <TextView
        android:id="@+id/textBankSsn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:gravity="center"
        android:textAppearance="@android:style/TextAppearance.Medium"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toBottomOf="@id/textBankAccount"/>

    ...

Check out content_bank.xml for the full XML layout.

With everything lined up, you can now easily send the data to your upstream API server. Just set an onClickListener for a button:


setSubmitClickListener(btnBankSubmit, {
           httpbinService.post(BankData(
                   editBankName.text.toString(),
                   editBankAccount.text.toString(),
                   editBankSsn.text.toString()
           ))
       }) {
           textBankRedactedData.text = getString(R.string.redacted_data)

           textBankName.text = getString(R.string.bankName, it.name)
           textBankAccount.text = getString(R.string.bankAccount, it.bankAccount)
           textBankSsn.text = getString(R.string.bankSsn, it.ssn)
       }


 private fun <T> setSubmitClickListener(btn: Button, httpPost: () -> Call<HttpbinResponse<T>>, printFunction: (T) -> Unit) {
        btn.setOnClickListener {
            progressBar.visibility = VISIBLE
            httpPost.invoke()
                    .enqueue(object : Callback<HttpbinResponse<T>> {
                        override fun onResponse(call: Call<HttpbinResponse<T>>?, response: Response<HttpbinResponse<T>>) {
                            printFunction.invoke(response.body()!!.json)
                            progressBar.visibility = GONE
                        }

                        override fun onFailure(call: Call<HttpbinResponse<T>>, t: Throwable?) {
                            Toast.makeText(this@DataSendActivity, "Unexpected Error", Toast.LENGTH_LONG).show()
                            progressBar.visibility = GONE
                        }
                    })
        }
    }

As a result, data in transit will be secured and your API will receive a token instead of the real SSN number: tok_sandbox_fMP3z4JUx8woswFg7WD2Ep.

Group 5

With this simple process, you can secure your data quickly, with zero additional lines of code.

Don't miss the next Developer Office Hours with our CTO

Join Us
Yuriy Yunikov Yuriy Yunikov

Engineering Manager at VGS

Share

You Might also be interested in...

vas-access-logs

How to Make the Most of VGS Access Logs

Yura Shafranyuk September 11, 2018

Image-for-blog

A Very Good Approach to Security

Marshall Jones August 28, 2018

spring-vgs-java

How to Achieve PCI Compliance with 3 Lines of Code Using the Spring Framework

Oleg Yatskiv August 20, 2018