Blog Infos
Author
Published
Topics
Published

πŸ‘‹ Hi and welcome to the third post in this series where we deep-dive into Android Security. This series focuses on theΒ Top 10 MobileΒ security threats as determined byΒ The Open Web Application Security Project (OWASP) Foundation, the leading application security community in our field.

Before checking this post, please consider checking out the previous one β€˜Insecure Data Storage’ which is available on my site, and on Medium.

⚠️ Please note that this series is for educational purposesΒ only. Remember to only test on apps where you have permission to do so and most of all,Β don’t be evil.

Finally, if you enjoy this series or have any feedback,Β please drop me a message. Thanks!

Introduction

In this helping of my series on Android Security, we shall take a look into the #3 threat to mobile application security as determined by OWASP, β€œInsecure Communication”.

When we talk about communication in the context of mobile security, we are actually referring to technologies that can transmit and/or receive data. This may include the device’s internet connection (via WiFi or otherwise), connection to the mobile network, Bluetooth, NFC, and so on and so forth. This unfortunately gives us a pretty broad surface area to cover πŸ˜… However, let’s address the big one today, as perhaps we will revisit this in the future!

The Internet

Unless an app has some very bespoke communication functionality or none at all, it’s more than likely it communicates via the internet with one or more services ΒΉ. This could take the form of requests to an API, visiting a webpage in an in-app browser and pretty muchΒ everythingΒ in-between. The list of possibilities is near-endless, which means there is plenty of attack surface for malicious actors to prey upon.

For the sake of brevity I won’t cover an β€œendless list”, let us instead cover some of the blindingly obvious points and answer the critical question of β€œHowΒ shouldΒ we be making calls over the network?”.

Top Tip #1: Always make calls using HTTPS

At the time of writing, we are already approaching the halfway point of the year 2022. However, believe it or not, we still live in a world where occasionally mobile apps do not transmit data via HTTPS.

β€œWhat is HTTPS and why does it even matter?”

HTTPS is the security-enriched use of the Hypertext Transfer Protocol (HTTP), the fundamental protocol (i.e. a pre-defined set of rules) used when communicating on the internet.

β€œOk, so the β€˜S’ stands for secure, but how does HTTP actually become HTTPS?”

HTTPS utilises Transport Layer Security (TLS)Β², another protocol, to communicate securely using cryptography to encrypt data in transit between client and server. This cryptography is achieved, in part, through the use of β€˜digital certificates’ (more on those shortly). Therefore, whenever an application sends data via HTTPS it is encrypted and avoids threats such asΒ man-in-the-middleΒ (MITM) attacks where an attacker can intercept HTTP calls, spoof them and let a victim believe they are talking to the legitimate server. It also makes eavesdropping via a compromised network extremely difficult, again thanks to the built-in encryption provided.

From an Android standpoint, if your app targets Android 9 (API level 28) and above, sending data via HTTP (i.e. cleartext) is disabledΒ by default. However, it is possible to disable this for all network calls through the use of theΒ network security config fileΒ or through a manifest fieldΒ android:usesCleartextTrafficΒ³. In generalΒ you should never do thisΒ and instead consider a cleartext ‘allow list’ within your network security file as seen below:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
  
    <!-- DO NOT DO THIS TO ALLOW CLEARTEXT -->
    <base-config cleartextTrafficPermitted="true">
        ...
    </base-config>
  
    <!-- DO THIS (BUT ONLY AS A LAST RESORT) -->
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">example.com</domain>
    </domain-config>
  
</network-security-config>

Again, wherever possible, avoid doing this and instead migrate all URLs to use HTTPS. Your users (and conscience) will thank you ✨

Top Tip #2: Don’t blindly trust user certificates

As previously mentioned, one key aspect of securely communicating over the internet is the use of digital certificates ⁴.

In order to verify the server isΒ actuallyΒ who they say they are, some form of certificate is required to prove the identity. However, a certificateΒ aloneΒ is not sufficient, as there would be nothing to stop an attacker from creating a fraudulent one and passing it off as legitimate. To combat this, we use a shared β€˜trusted third-party’ known as a β€˜certificate authority’ (CA) whose signature on a certificate proves a certificate is authentic when the CA is trusted by both the client and server ⁡. Your Android device comes pre-loaded with a common list of CA’s that are β€˜trusted’, which means you can make secure calls to the internet immediately without (usually) any issues.

However, Android also allows users to supply their own β€˜trusted’ certificates. The most common use case for user certificates comes through their use with proxy software such as Charles, Fiddler or Wireshark, allowing the capturing of data sent by a device for debugging purposes. They will often provide a certificate for a user to add to their device while proxying through the software, allowing the decryption of secure HTTPS calls and the contents to be freely viewed/modified. For debugging purposes, this is often invaluable and extremely useful,Β but allowingΒ anyΒ user certificate on a production app is a huge security lapse.

You might well be vulnerable if your network security config files contain something similar to the example below. In fact, if your app does not target Android 7.0 (API level 24) or above it will act like this by default ⁢. This example would allow user certificates to be available on all configurations of the application, including any production/app store builds.

<!-- DO NOT DO THIS -->
<network-security-config>
    <base-config>
        <trust-anchors>
            <certificates src="user" />
        </trust-anchors>
    </base-config>
</network-security-config>

The recommended approach is to allow user certificates toΒ only be used by your application during debugging. i.e. non-production and non-public facing builds. Thankfully, this is quite straightforward to implement through the use ofΒ debug-overrides.

<network-security-config>
    <debug-overrides>
        <trust-anchors>
            <certificates src="user" />
        </trust-anchors>
    </debug-overrides>
</network-security-config>

Nice. πŸ₯³

Another noteworthy point here. Should your server use aΒ self-signed certificateΒ and not one provided by default CAs, you can also provide the raw PEM or DER certificate file(s) within your app to allow them to be used when networking. By adding one or more of these files toΒ res/raw/trusted_roots, it becomes possible to import them as a certificate source usingΒ @raw/trusted_rootsΒ at the top or domain-specific level.Β The docsΒ are especially helpful in this slightly more niche case, so please give them a read!

Top Tip #3: Certificate pinning & transparency

On the subject of certificates, to further bolster your security you may wish to or have considered certificate β€˜pinning’. For those who aren’t aware, certificate pinning is the act of checking the chain of certificates for a request against an β€˜expected certificate hash’ to check it is present. In reality, this is usually the hash of one (or more) of your certificate’s public key and is hard-coded into your application as part of your network layer or again, as part of your network security config XML file.

This is aΒ veryΒ common approach utilised by apps to ensure they are only communicating with the expected server. Nevertheless, this approach has a number of issues, including requiring app releases for certificate rotations and ensuring you make the best choice when it comes to choosing certificates to pin in the chain.

However, there is another slightly lesser-known but arguably much better option on the table πŸ‘€

Certificate TransparencyΒ (CT) is a growing alternative approach and addresses some of the pain points that come with working with certificate pinning. CT is achieved by CAs publicly logging when they have issued a new certificate to a log server. Critically, these log servers are β€˜append only’, meaning they can only addΒ newΒ data to them. When a new certificate from a CA is issued, the log server issues a signed certificate timestamp (SCT) which can be verified by a client. As there is no longer a reliance on public keys of certificates, the need to release an app when certificates rotate is eliminated and the certificate’s authenticity can be guaranteed.

Matt Dolan’s talkΒ β€œMove over certificate pinning. Certificate Transparency is here!” gives an excellent insight into how to implement this in your apps, as well as a great overview of both pinning and CT.

Top Tip #4: Don’t log your calls

You’d be amazed how many times I have downloaded an app to my device, used it for a while, opened logcat and to my horror been greeted by the networking calls I just made staring me in the face. I really wish I was joking. Login credentials, full headers, the works. I’ve seen pretty much everything. Worst of all, I saw itΒ just this month⁷.

Many of us will use OkHttp within your app’s networking layer and thus potentially also be using theΒ HttpLoggingInterceptorΒ to print your networking calls to logcat. There is absolutely nothing wrong with this, so long as this codeΒ does notΒ make it to the production/public-facing version of your app.

You should certainly consider disablingΒ allΒ logging in your production apps by using R8 to strip theΒ LogΒ class of its functionality. This can be achieved by adding the following rule to your obfuscation file:

-assumenosideeffects class android.util.Log {
    public static boolean isLoggable(java.lang.String, int);
    public static int v(...);
    public static int i(...);
    public static int w(...);
    public static int d(...);
    public static int e(...);
}

Job Offers

Job Offers

There are currently no vacancies.

OUR VIDEO RECOMMENDATION

, ,

Migrating to Jetpack Compose – an interop love story

Most of you are familiar with Jetpack Compose and its benefits. If you’re able to start anew and create a Compose-only app, you’re on the right track. But this talk might not be for you…
Watch Video

Migrating to Jetpack Compose - an interop love story

Simona Milanovic
Android DevRel Engineer for Jetpack Compose
Google

Migrating to Jetpack Compose - an interop love story

Simona Milanovic
Android DevRel Engin ...
Google

Migrating to Jetpack Compose - an interop love story

Simona Milanovic
Android DevRel Engineer f ...
Google

Jobs

assumenosideeffectsΒ strips any calls to the provided methods from within your app as it assumes the return values aren’t used. This will ensure no logs are output by your app.

However, this extreme approach may not work for everyone. Alternatives include using custom logger implementations (through libraries such asΒ Timber) to discard logs when the app is built using a certain flavour, or just do not useΒ LogΒ at all πŸ˜… The choice is very much up to you and your situation!

Top Tip #5: If in doubt, use your head!

I do apologise if this sounds condescending, and admittedly this is not just limited to this particular area of security, but often a sprinkling of common sense when working with areas such as networking can make a big difference.

Try to think about the data you send to the server and the impact it might have if it was intercepted.

Here are some example questions you could be asking yourself:

  • Do I need to be sending {XYZ} data in this network call?
    – You ideally should be sending the minimum amount of information required
  • Is {XYZ} dangerous in the wrong hands?
    – What could an attacker do with the information should it be intercepted
    – What is the worst-case scenario?
  • Does {XYZ} require appropriate authorization and/or authentication to use?
    – Can the networking be locked down further using roles or identity verification⁸

I hope these examples kick start a conversation with yourself, your team and hopefully other engineers!

Next up πŸš€

In the upcoming posts within this series, we shall explore more of the OWASP Top 10 for Mobile. Next up is #4Β Insecure Authentication

Thanks 🌟

Thanks as always for reading! I hope you found this post interesting, please feel free to tweet me with any feedback atΒ @Sp4ghettiCodeΒ and don’t forget to clap, like, tweet, share, star etc

Further Reading
Footnotes

[1] Assuming you remembered to add theΒ android.permission.INTERNETΒ permission… 😬

[2] β€œThe artist formerly known as Secure Sockets Layer (SSL)” πŸ‘¨β€πŸŽ€ β€” TLS mostly replaced SSL when it was deprecated in 2015

[3] Available as of Android 6.0 (API 23) but ignored in API 24+ if a network security file exists

[4] These certificates areΒ stillΒ commonly known by some as β€˜SSL Certificates’, despite SSL being deprecated in favour of TLS

[5] Yes, I am afraid to say that in 2022 theΒ entire internetΒ hinges on this trust of third parties.Β Oh, and it does go wrong. Some nightmare fuel for you there, you’re welcome!

[6] The β€˜default network security behaviour’ of apps targeting different versions is described in theΒ docs here.

[7] Well, β€˜this month’ at the time of writing. It was also responsibly disclosed to the relevant security team of the company

[8] Keep an eye on my blog for more on this in future…

Thanks toΒ Omolara Adejuwon

 

 

This article was originally published onΒ proandroiddev.com on August 16, 2022

YOU MAY BE INTERESTED IN

YOU MAY BE INTERESTED IN

blog
Protect your user’s privacy and adhere to possible technical requirements
READ MORE
blog
Security and privacy are the two most talked about topics these days. Like any…
READ MORE
blog
πŸ‘‹ Hi and welcome to the second post in this series where we deep-dive…
READ MORE
blog
πŸ‘‹ Hi and welcome to a new series of blog posts in which we…
READ MORE

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.

Menu