This post was made prior to the OWASP Top 10 2024 update - please see my blog post for more details on the 2024 Top 10

👋 Hi and welcome to the fourth 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 Communication’ 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 #4 threat to mobile application security as determined by OWASP, “Insecure Authentication”.

But what does authentication involve? Well, put simply, authentication is the process of verifying a user’s “identity” is what they claim it to be. Once verified, this identity is then often used to authorize the user to access a service, data or other restricted resource. 1

Authentication is achieved by using at least one of three basic authentication factors: 2

💭 Something you KNOW

  • Such as a password, passphrase, user id, etc 3

🎁 Something you HAVE

  • An authorisation token, a physical crypto-key, an authentication code, etc

👀 Something you ARE

  • Via your own biometrics. i.e. fingerprint(s) or forms of visual recognition such as facial/retinal recognition

In theory, the more of these factors that are used, the stronger the authentication is and the harder it becomes to pretend to be someone you aren’t. This is, in fact, the guiding principle behind multi-factor-authentication (MFA) and hopefully something you are familiar with and using already when it comes to your own authentication practises!4

That said, these individual authentication factors aren’t foolproof and still require care to be taken by the developer in order to ensure the user is protected and your app is secure. So let’s do just that!

What’s the passw*rd?

Something that certainly isn’t unique to Android apps is users making poor decisions when it comes to password security. Given when data breaches occur the most common choices are usually password, 12345, qwerty or similar variations, we can assume that when given the option users may opt for incredibly simplistic and insecure passwords.

However, as developers, we have a duty to ensure that when users create passwords they are as secure as possible by enforcing ‘password policies’ which will (hopefully) encourage users to create not only strong passwords, but also unique ones.

“Ok, but what makes a good password policy?” I quite clearly heard you say. 🤗 I am so glad you asked, here are some tips on how to come up with one.

  1. Set a minimum length

    Firstly, ensure your policy has a minimum length of characters that is required. It should be obvious that a longer password is generally more secure than a shorter one, but choosing character limits that adds security and also allows users to generate passwords they will find memorable can be difficult. A good minimum number for this task, and also recommended by the National Institute of Standards and Technology (NIST), is 8 characters.

    Ideally, you should also consider the maximum length of any passwords to be at least 64 characters to facilitate and encourage totally unique passwords or phrases. Visually reinforcing longer passwords within your app’s UX is also a great approach to ensure users make better choices.

  2. Reconsider the use of ‘complexity requirements’ When you read password policy you probably instinctively thought of rules that enforce a mix of letters, numbers, and special characters, as this fairly common place. The theoretical aim of rules of that nature is to make it more difficult for attackers to simply guess or use brute force to crack a password. However, guidance on this has shifted in recent years due to concerns that such complexity requirements actually lead users to create more insecure passwords5 🤯. In this case, perhaps less is more! Giving your users increased flexibility may encourage longer, harder to crack passwords, which is better for everyone.

  3. No hints allowed! You may occasionally come across applications that ask you to supply a memorable phrase as a hint for future password recovery. This is certainly something you should avoid as it gives extra information to a potential attacker as users routinely choose hints which severely compromise their passwords 😅 The next point highlights exactly why.

  4. Knowledge is porridge6

    What was your first pet’s name? Who was your favourite teacher? Where were you born?

    Be aware that security questions might occasionally seem like an added layer of safety, but in extreme cases can be (and have been) obtained by social engineering. Social engineering plays upon our human-emotions and as humans are fallible, much like software, even basic social engineering could give malicious actors enough information to work towards compromising a user’s identity. Depending on your visibility online, you might well have already been leaking some of this information yourself without realising7. Social Engineering has caused numerous high profile security breaches in the last decade and is an attack vector that is seeing an increase in popularity.

  5. Best practises change over time This guide is just that, a guide. Please make sure you consult your own cyber-security team (or other professionals) to determine if your current policy is up to scratch. Guidence on passwords has continuously shifted for decades, and will lilkely continue to do so for many more to come!

But wait, there’s more. Once the password is created there are some further considerations to take on board:

  1. Password expiration: Setting a limit on how long a password can be used before it needs to be changed. This helps to limit the window of time during which an attacker can use a cracked password.
  2. History: Preventing users from reusing passwords that they have used in the past. This helps to prevent attackers from using passwords that have been compromised in previous breaches.
  3. Use of password manager: Encourage users to use password manager that can store their password securely.
  4. Remember Me: If you provide some form of ‘remember me’ functionality during sign-in, never store the user’s password locally on the device. Instead, utilise a long-life authentication token that can easily be revoked if needed.

With these tips - you can do your very best to help users make a well-informed and secure password. You can hopefully sleep easy knowing you have done your part, and as long as the users do theirs, their passwords are secure!

Clearly, passwords continue to present a very real security problem for apps, but I am pleased to say the future is beginning to look to be somewhat brighter…

Passkeys

When I originally wrote my very first draft of this blog post, I pretty much wrapped it up here. However, as a consequence of tinkering and toying with this post for a while, Google has now already begun the push to a post-password world in the form of ‘passkeys’. Doesn’t technology move fast! 😅

In fact, Google, Apple and Microsoft have all committed to providing a common password-less solution through the adoption of the FIDO (Fast IDentity Online) Alliance’s passkey standard. So this isn’t something to be sleeping on 👀

Pass-whats?

But what even is a passkey? Well, a passkey is a unique cryptographic key pair used to identify a user and their associated account for a given service. When a new passkey is created, the private key is saved on the issuing device with the public key being sent to be securely stored by the service.

This may sound just like bog-standard public key cryptography, and guess what? It is! Albeit, with the additional requirement of requiring authentication via the issuing device. If we think back to the list of authentication factors, this new flow requires something you have (i.e. the issuing device) and something you are (i.e. biometrics) or know (i.e. device PIN).

The good news is, from a user’s perspective, there’s very little that changes from a standard password flow. When a user is prompted to sign-in via passkey, the user approves the sign-in with the same authentication factor that the user has to unlock the device, such as their biometrics, password or PIN. Should a passkey exist for the user, then this authentication is enough for the user to continue - no further action required. If the device has yet to issue a passkey for that user and account, one is created and the sync process between the issuing device and service is also initiated to ensure the user can continue to use the device.

Passkeys in Android

Over the last few months, Google released a bundle of new online content (see: Further Reading) to aid Android developers in providing passkey support.

The first thing to note is passkeys are only supported on devices that run Android 9 (API level 28) or higher, meaning older OS versions will need to fall back to an existing password flow. Sadly we haven’t eliminated passwords completely, but this is progress!

Under the hood, using the androidx.credentials:credentials suite of libraries, we can utilise the CredentialManager class to aid us in the generation of credential requests and the handling of the various response types. I won’t discuss the full technical implementation here, but rest assured the official docs have you covered 😎

If this sounds like something you’d like to learn more about, I would highly recommend reading the original Bringing Passkeys to Android & Chrome announcement blog post and watching the associated YouTube video before attempting to implement this yourself using the Sign in your user with Credential Manager development guide.

In any case, you may also wish to check out the sample app provided by the Google identity team to give an idea of the best practices surrounding passkey implementation.

Hopefully, in a few year’s time, we’ll have totally ditched the dodgy passwords and have made our apps much more secure in the process!

Next up 🚀

In the upcoming posts within this series, we shall explore more of the OWASP Top 10 for Mobile. Next up is #5 Insufficient Cryptography

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. Spoiler alert, we will revisit authorization in a future blog! You can swot up in advance by checking out OWASP - M6: Insecure Authorization 

  2. You could also use ‘location’ and ‘behaviour’ as separate authentication factors. However, to keep it simple I have limited it to the most common 3 factors. 

  3. Assuming that you, unlike me, can remember your passwords! In any case, I highly recommend a decent password manager such as 1Password 

  4. Please use MFA whenever it’s available. It usually takes no time at all to set up! 

  5. For example, JohnDoe@1992 could be cracked a lot easier than android is my favourite mobile os 

  6. One of my favourite ‘Thick of It’ quotes (NSFW) 

  7. I’ve never (to my knowledge) posted my dog’s name on the internet - just in case