Data Protection For Mobile Client-Server Architectures

That’s the follow-up of several talks about data protection for mobile applications I gave at the end of 2015. Geography is wide: twice in Ukraine (mdday.lviv.ua, CocoaHeads Kyiv #7); once in Amsterdam, Netherlands at do{iOS} conf; and in Minsk, Belarus at CocoaConfBy.

We, mobile app developers, usually consider security to be a complicated topic, and that is why security talks are rather tedious. I also watched lots of talks like those. While some security concepts are very difficult to understand, it’s also almost impossible to remember and implement them. I decided to take the other way round and make my talk about data protection easy to grasp, with a plenty of cute pictures.

Look on the slides, watch the video of my talk at do{iOS} conf, or read the whole story.

Real world security vs cyber world security

Let’s start with a real-world security. Meet two dodo birds: Alice and Bob. They are rare species and want to secure themselves from Eve, a Fennec Fox with looooong ears intended to listen all birds’ secrets. When birds notice Eve, they fly away to the bushes.

Eve-the-Fox eavesdrops birds chatting, but they can fly away to the bushes

Well, in the real world things are clear: when somebody wants to hear your secrets — you can physically move away. Avoiding dangers is a part of our nature.

In the cyber world information security requires us to solve puzzling problems for which we don’t have intuitive instruments.

We only know the general direction:

  • make communication confidential
  • and limit access to the stored goods

It can be surprising, but every program is a potential target for attackers who will try to find a security vulnerabilities in our apps.

We — developers — are responsible for keeping things secure from bad guys.

We really care about users’ data. We want to protect data in the storage (saved to the database, files, NSUserDefaults, etc) and on it’s way from an app to a server.

Protect the data on its way to the server

Developers tend to think mobile apps are quite safe from malicious attacks in their neat sandboxed environments. This is only partially true: data-in-motion is still at risk, and the risk is high: all sorts of man-in-the-middle and passive eavesdropping attacks are still efficient, if you don’t protect the data the right way.

Why is this happening? Security is thought to be tangled and hard to implement. Instead of thinking about building the app based on the fundamental security principles, developers prefer to copy the quick solution from StackOverflow or to implement already existing cryptoalgorithms themselves. It leads to buggy software, full of vulnerabilities and security holes that can be easily cracked.

Thanks to the Apple ATS policies, now almost every iOS9 application uses HTTPS. HTTPS relies on SSL/TLS protocol, that — unfortunately — has a number of security issues and a lot of moving parts, which are easy to break.

Using HTTPS alone doesn’t make your app very secure: there are lots ways to break SSL encryption. From the attacker perspective, it looks like Alice wears a paper hat and Bob encircles himself with a handmade fence, and they feel secure. But they are not.

Using HTTPS with default setup is like using paper hat and handmade fence against Eve

It’s very important to do SSL right to be more secure: disable old protocols (like sslv3), use long encryption keys and pin certificate inside the client. Well, you can read more in that tiny cheat sheet.

SSL pinning is one of the easiest things to implement inside iOS app that complicates MitM attacks. You just need to pin server’s certificate inside the app, encrypt it and store in a secure place. Well, of course, don’t forget to update certificate before it expires. Many apps are already using SSL pinning, for example, Paypal. As usual, there are amazing libs that can be helpful! For example, it takes only three lines of code on Swift to pin certificate using Pitaya lib.

But using SSL encryption is not enough. SSL was proven to have weak Forward Secrecy, which means that if the encryption key is leaked, all past and future(!) messages can be decrypted. Forward Secrecy is based on using ephemeral keys — keys that are constantly changing — and even if current key is revealed, only small portion of messages is decrypted.

Encrypting data with persistent keys causes the illusion of safety, but it’s just an illusion.

Always encrypt crucial data with ephemeral keys that are re-generated each session, and no one will be able to grab it using the soldering iron.

Before sending data, client and server negotiate about temporary key and use it only during current — rather short — session. Opening new session requires to generate new temporary key. It sounds quite tricky, but there are cool libs for that! Themis and OTRKit libs provide easy client and server interfaces to add encryption to your current client-server architecture.

Keep users data correctly

Okay, enough about data in motion, securing data in storage is also important. iOS has own crypto, protecting user’s data while your device is locked. But what if device is stolen and unlocked?

Wherever you store sensitive data, please, make sure it’s encrypted.

You don’t need to implement everything yourself. Realize possible security risks for your specific app, build the stout architecture based on CIA principle (confidentiality, integrity, authentication), use right tools, and own brains — this is a proper way to create the app that will take lots of time to break.

It’s quite simple: pick the good library, generate the encryption key (aka master password), encrypt data before writing to the storage, decrypt it after reading back. And of course, don’t put your master password plaintext inside your app or in the NSUserDefaults. Use Keychain (SSKeychain and Valet are nice wrappers) or generate master password ‘on the fly’ using custom math formula and KDF.

Alice and Bob build stout secure architecture, poor Eve is crying in the corner

To summarize, securing your app is rather simple:

– use HTTPS and make sure you’ve disabled old and weak ciphers;
– implement SSL pinning, but encrypt the certificate and keep it safe;
– encrypt data in motion with the additional layer of encryption using the ephemeral keys;
– encrypt data before putting it in the storage and remember to store master key secure or to compute it “on the fly”.

What to see next


Let me know if you care about security as much as I do =)