But I’m not going to dwell at all on the language used to write Android apps in this chapter. Instead, I am going to look at instances where code written can pass on vulnerabilities to other parts of the system, like the back-end servers. I will also talk about some of the things you need to keep in mind with regard to your user’s safety and privacy. So, let’s get started. Let’s look at privacy first.
Privacy
Data privacy has become a big deal lately. I mean, it always should have been, but the past few years have given us such wonderful headlines that privacy is almost always in the news. As a security practitioner, I’m thrilled that more people give a damn. As a security practitioner, I am also appalled at the amount of blatant violations of privacy still going on. Privacy is such a big deal that in May of 2018, the EU implemented GDPR or the General Data Protection Regulation. The law itself is fairly straightforward and logical, but interestingly, it allows for warnings and fines to the tune of up to 4% or 20 million Euros based on certain infringements. To date, 34 fines have been issued to various institutions including a hefty 50 million Euro fine to Google. Whether these have been paid or not are not part of this discussion, although I know Google was appealing their fine. The point is, however, to understand that we’re getting serious about privacy.
If you’re a developer that requests for and stores a user’s private information, then you have a duty to keep that data private and safe. Depending on who you ask, the information one would consider private varies, but for a blanket definition, we typically define private information as information about a user that is generally not shared with the majority of the folks he meets. So, things like home address, gender, marital status, age, bank or credit card information, and phone number are usually considered the major components of information that a person would want to keep private. But let’s analyze why first. I mean, why would you want to keep this information private? One can argue that by having that information about someone, there is precious little that can be done directly to affect him other than sending unsolicited pizza or a mob to his house or prank calling him until he disconnects his phone number. I’d like to pause here and talk about that mob I just mentioned. While I played it off as more or less innocent, there is one specific case where people have even died when mobs have been dispatched to their house. What I’m referring to here is the practice of swatting.
Swatting
Swatting takes place when someone malicious that knows your home address calls up emergency services and then deceives them into believing that there is a life-threatening emergency taking place at your house – typically, an armed person that has already hurt someone or a terrorist suspect. The resulting visit to your home by the SWAT or emergency response team can sometimes have catastrophic results. There was a case in 2017 where a 28-year-old father of two was shot by a police officer. The victim was not even related to the group that initiated the swatting incident. He was an innocent victim that had the misfortune of having his address used for the purposes of winning a bet.
Let’s go a little deeper into what happens when an emergency response team heads to a victim’s house. They head there on full alert prepared to confront an armed and dangerous individual. The victim has no idea why someone has just broken into his home. He doesn’t know if it is a friend or a foe. During heated times like that, sometimes a victim may resist or at least take on a defensive role. To the emergency response team, this may look like a challenge or threat, and if cooler heads don’t prevail, then someone is taking a shot at the perceived aggressor. This is one way to look at why safeguarding your users’ home addresses is important.
Aside from swatting, there is another key reason for keeping your user data private. And no, I’m not talking about the nasty headlines written about how badly you screwed up and allowed 100,000 user accounts to get leaked. I’m talking about social engineering. The more personal, private information that a social engineer has on a victim, the more plausible he can make his story. Humans are wired to trust. They are also wired to default to the truth in most cases. By using subtle cues of private information on a victim, it is a lot easier to push them into believing you and your story. “Oh this guy already knows about my information, so I guess he IS calling from that bank to help me with my bank account” would be a response from a hapless victim on the other end of the phone.
So, then, what’s the secret to keeping a user’s data protected? It’s not really a secret. You have to protect your own infrastructure where the data is stored. One of the first steps I would advise would be to collect as little private information from a user as possible. It may be tempting to say “Let’s just ask for this data now and figure out what to do with it later,” but I think that is a bad idea. If you have a genuine need for the data, then ask for it – especially if it is something you can’t do without, like a shipping address. The concept is that if you have the bare minimum amount of data, then you can rest easy knowing that the fallout from a breach isn’t going to be that catastrophic, especially for the user.
- 1.
Generate a unique user id for him that you save in your main, “hot” database. This database is what gets used all the time.
- 2.
Take all the private information and store it in a separate database that does not link to the main ecommerce site. This database is the more secure, “cold” database that holds private information. Typically, for the ecommerce site, it should be a write-only database. Information just goes in and does not come out to the ecommerce site.
- 3.
With the information entered, take the private information that you just saved and render it illegible by using a basic algorithm such as blanking out all characters except the first character of each word. You can see an example of that in Figure 2-3. Once this is done, store it in the main database.
Another approach is to designate aliases to parts of the information stored. So, for his Shipping Address, you can get him to call it by an alias like “Home” or “Work.” Then when it is read back, the address shows either Home or Work. Since the user knows what the home or work address is, he has all the information that he needs when he checks out. An attacker, however, will not be able to understand what the true address of the person is. All he will see is the word Home or Work.
The concept here is that the user will never need to be told what the information he entered is. He already knows that so there’s no need to show him exactly what he entered. Instead, he will only want to modify or write to the profile data. By using a technique like this, you can greatly limit the exposure of your users in case a data breach takes place.
Data Security
You will notice that each directory has its own user and group id. Essentially, Android will allow an app to write into its own space at will. Android apps are unable to write to any other location other than the /data/data directory.
Data Encryption
The BMW Connected App makes use of SQLCipher to keep its data encrypted on the device. In Figure 2-6, we run the file command on the database files pulled from the BMW Connected App. You can clearly see how the non-encrypted databases were correctly identified as SQLite files, but the ConnectedDB.db file, which uses SQLCipher, shows up as plain data. That is because it is encrypted. Figure 2-5 shows a hex dump of the ConnectedDB.db file.
After this, you can write code as you normally would if you wanted to use android.database.sqlite.SQLiteDatabase, except this time you would use net.sqlcipher.database.SQLiteDatabase instead.
Calling Up Sensitive Information
Network Security
By now I think every developer should know to always send their network traffic over SSL or TLS. Network traffic sent over plain HTTP can be very easily sniffed by using a tool like Burp Proxy. All you would have to do is to fire up Burp Proxy, which listens on port 8080, then add a proxy to your Android’s Wi-Fi connection to route all traffic to Burp Proxy. Of course, both devices have to be on the same network. These days, even plain old HTTPS is not enough either. You can easily circumvent the hassles of sniffing TLS traffic by installing Burp Suite’s TLS Certificate which the app ends up recognizing. After this, it has no reservations about sending Burp Proxy all its TLS traffic as well. What’s the solution then? The main one I wanted to cover here is known as SSL Pinning.