Chapter 4. Mitigating Vulnerabilities
In Chapter 1, Introduction to Software Security, we already discussed the most important vulnerabilities that can be exploited in order to compromise your application. Now, you need to learn what measures you can take in order to address these vulnerabilities and make your application more secure. What easy steps can be taken in order to achieve this?
This chapter will show you how to mitigate vulnerabilities. Removing or at least treating vulnerabilities will significantly reduce the risks of your system. We'll begin by learning how to validate input fields. We'll also learn how to avoid code injection, especially the most common one: SQL injection. We'll then see recommended practices when handling user credentials and we will learn how to make our components more secure in order to avoid vulnerabilities in the interapplication communications.
The topics that will be covered in this chapter are as follows:
Input validation
Permissions
Handling users' data...
According to the Android development guidelines, the lack of sufficient input validation measures is one of the most common security problems in Android applications. There are several problems that can be derived from insufficient input validation such as buffer overflows, null pointers, off-by-one errors, inconsistencies in the database, and even code injection problems.
Now, we will see some tips that will help us to mitigate this vulnerability.
We can use the inputType
attribute in order to limit the possible characters the user can set in a field. For example, if we have an EditText
field where we want a telephone number, we can define the EditText
as follows in your layout file:
Although this should not be considered a security feature, it can help to mitigate...
The Android sandboxing system alienates applications from each other. This means that the applications must explicitly share resources through the use of permissions. In order to access the additional capabilities, we need to declare the permissions that we require in our manifest, and these permissions must be accepted by the user after installation.
If our application does not have access to many permissions, it reduces the vulnerabilities that may affect our application. When developing the application, we should always try to request as few permissions as possible. For example, try to store data locally instead of asking for a permission for external storage. If it is not possible, we can obviously request permissions but we should address the vulnerabilities that these permissions can lead to.
If the system-defined permissions are not enough, we can create our own permission to use, which will be defined and will require other entities to ask for permission when required....
Handling a user's data and credentials
The best way to handle a user's data and credentials is to minimize the use of this information. We should have access to the user data, store user data, or transmit user data only when it is completely necessary.
In the cases where handling user's data and credentials is necessary, there are some considerations that we should have as developers:
Consider using hash or nonreversible forms of data if the logic of your application allows it.
Do not expose user's data to other applications on the device. Try to make the interprocess communication as strict as possible. Programming with more flexible interprocess communication permissions can be more comfortable, but it can also be a huge vulnerability in your system.
Minimize the use of APIs that access sensitive information, especially when the information is personal data. Different APIs have different privacy policies and can even be malicious sometimes.
Make sure you understand what each and every piece...
Interapplication communication
As we seen in Chapter 2, Security in Android Applications, there are ways to communicate between Android apps as they cannot share data due to Application sandboxing. This communication raises security challenges that should not be overlooked.
When using Intents, there are two kinds of vulnerabilities: unauthorized Intent receipt and Intent spoofing. An unauthorized Intent receipt happens while using an implicit Intent. As the Intent is broadcasted, there is no guarantee that the intended recipient will receive it. A malicious application can declare an implicit Intent by declaring all the possible actions in the intent filter. This kind of interception can lead to DoS and phishing attacks.
The best way to protect against this kind of vulnerability is to be very cautious with implicit Intents.
Note
If you are sharing some private information, avoid using implicit Intents.
When possible, and especially while sharing private information, your application...
In this chapter, you learned how to mitigate the most important vulnerabilities that can affect our Android application. You know how to use regular expressions in order to validate an input. You have also learned about SQL injections and how parameterized queries can help overcome this vulnerability. We know how to handle user and critical information. Finally, we learned how to use Intents and content providers in the most secure way possible.
In the next chapter, you will learn how to preserve the privacy of our data. You will learn how to handle the data when stored locally, the different possibilities, and ways to secure them. You will also learn about cryptography and how to encrypt local data.