“Borderline bulletproof” security for API keys

In episode 5 of my Keep in Touch podcast I shared some thoughts on how I currently think about protecting credentials, API keys, and secrets (summarised as keys for the rest of the post) for 1st and 3rd party services and APIs. This blog post is a recap of those ideas and also a call for feedback and input from you.

The risks

The problem I am talking about addressing, is related to the fact that many applications embed keys in their binaries. These keys are required to authenticate (and authorise) the app, the user, or both with remote services. These services could be public or private APIs. Similar considerations apply if these APIs are 1st party or 3rd party.

If these keys are bundled with the app, a nefarious attacker could extract them and then impersonate the developer.

It’s not my intention to teach bad actors how to execute their plans, but I do want to give a few examples of some attack vectors that could lead to sensitive information falling in the wrong hands:

  • the nightmare scenario: the attacker could run a man-in-the-middle attack by running a WiFi hotspot or could be operating one of the nodes on the internet between the device and the APIs the app connects to
  • the easier than you’d think scenario: the attacker could run an on-device proxy (such as the brilliant Charles for iOS app that I use daily for non-nefarious reasons), and monitor all traffic
  • the attacker could grab the app binary (ie. apk or ipa) and do a string search for key-like strings
    Any of the above could lead to the attacker obtaining the keys that the app uses to authenticate itself against remote servers. Once they get these keys they can start impersonating the app and its users.

The hypothesis

I believe that by not including any keys in the app’s binary and by provisioning these credentials only via a channel owned by the operating system that uses SSL pinning, the risks mentioned above can be reduced or even avoided.

SSL pinning is essential in order to prevent an attacker from inspecting the traffic between the client app and the remote endpoints.

Animated GIF showing the way keys can be securely transmitted from cloud to app to server. This flow is described in detail below

This animation attempts to illustrate the approach I am suggesting:

  1. Provision the app without any keys
  2. Attempt to detect if the app is running on a jailbroken / rooted device, and bail if that is the case
  3. Upload the necessary keys to the Trusted Cloud provided by the Host operating system (i.e. CloudKit for iOS apps) using another app (i.e. console, browser, etc)
  4. Enforce read-only access to these keys for the client app
  5. Upon (first) launch, fetch the keys from the Trusted Cloud
  6. If the keys must be stored, only store them in a keychain or in a secure enclave
  7. Use the keys to communicate with the Server using an SSL pinned connection
  8. Should the keys become compromised, they should be replaced, and the client apps should naturally fetch the new keys. For this reason, getting the new keys should not require the previous keys.

The steps above rely on the fact that the mobile OS provides a cloud service that uses SSL pinning in order to communicate to the client apps. Without it, there cannot be a secure key provisioning mechanism and the entire flow falls apart.

The checklist

Often times the security considerations come in “late” or “after the fact”. To assess the state of affairs, and to add more protection going forward, I would go over the checklist below:

  • Limit the number of people who have access to the credentials. Replace the credentials when these people leave the job.
  • Never embed the keys in the codebase
  • Never grant the build (or distribution) servers access to the keys
  • Only trust the cloud service that belongs to the platform vendor for your app (i.e. CloudKit for iOS apps, Firebase for Android apps.)
  • Avoid storing the keys anywhere (on the device) unless really necessary
  • If the keys must be stored, then the only acceptable place is the Keychain
  • Avoid bundling black-box libraries. If the libraries use networking, inspect all networking traffic
  • Do not use a 3rd party networking library unless absolutely necessary. Always check the source code of such libraries
  • Never be the largest consumer of any one technology, framework, or library
  • Only load the keys at the code level that really needs them. Do not pass them through the business layer, particularly if there are 3rd party analytics or logging libraries bundled with the app
  • Obfuscate the code and avoid obvious naming strategies for the keys
  • Check the app’s signature / hash or anything else similar that guarantees that the binary has not been tampered with
  • Be mindful of jailbroken or rooted devices but never change the code in order to support them
  • Do a quid-pro-quo vulnerability analysis with a trusted partner (make sure dinner or beer is something at stake if an issue is found)

If you have more to add to this list, I would love to hear from you!

Closing comments

I think of myself as a security minded person, but I am by no means an expert. I offer no guarantees that implementing the steps above is going to remove or prevent any security related problems for a system I have not seen before, but, based on my current knowledge, I do believe it is the closest thing to a “borderline bulletproof” approach to securing keys and credentials that native apps use.

Lastly, I sincerely hope that, if you read this and have identified a flaw in my reasoning, or if you can spot an oversight, you will share with me (ideally with a solution in tow) so I can update the article.

3D Touch vs. Long Press

Apple announced the new iPhone 6S line at their September event. One of the tent poles of their new iPhones is 3D Touch, a hardware feature that provides “depth” to touch interactions. An argument can be made that this feature can be replicated by a Long Press (a gesture that is already available).

Interestingly enough, almost all the interactions demoed during the event could be built today, using a UILongPressGestureRecognizer. Even the taptic feedback could be faked with a vibration.

Here are some of the differences between the two gestures that I can think of.

  1. Resting a finger on the screen could mis-fire a Long Press, but not a 3D Touch
  2. 3D Touch can provide instant gratification. Long Press gestures are defined by a minimum touch delay, therefore they would be laggy in comparison
  3. It would be very difficult to implement an app with multiple Long Press gestures, but it would be straight forward to mix a Long Press gesture and 3D Touch
  4. Long Press does not provide depth. Games can benefit from using this feature

Neither 3D Touch, nor Long Press gestures are discoverable. That is potentially why we have not seen many Long Press implementations this far. Looking at the Apple Music app, the Long Press gesture (on a For You playlist for example) opens the overflow action menu. It will be interesting to see if 3D Touch replaces that, or augments it in some way. Even the Instagram implementation doesn’t really “need” 3D Touch to offer a preview of the selected photo. A one second tap could provide the same functionality, albeit with a bit of a delay.

I’m thinking of an analogy with the home button. Pushing it down twice takes the user to multi-tasking. Tapping it twice invokes the “reachability” which makes the screen slide down. I often forget that the latter feature even exists… Long pressing an app’s icon will compete with the gesture that invokes “wiggle” mode. It will be interesting to see if users will be confused by the two gestures.

I have a feeling that many developers will start implementing Long Press gesture fallbacks for 3D Touch and that more and more apps will start providing Peek + Pop behaviours in their applications. This alone can be a huge win for many users out there, as long as the developers don’t start hiding essential functionality behind a gesture that I believe is not very discoverable. (Did you know that a Long Press on the back button of OmniFocus takes you to the app’s home screen?)

Notes:
I have not used an iPhone with 3D Touch yet (pre-ordered mine yesterday) so many of the things above are just guesses.

The one fear I have is that the 3D Touch edge-screen-swipe multi tasking gesture will interfere with the back navigation gesture. I sure hope I’m wrong…

Smart Lock – I called it

In my Log In post I was hoping that One day, smarter Log In pages would be able to Trust my location. A mere 2 days later, Google announces Smart Lock (as part of Google Play Services 6.5 and Lollipop).

The Verge provides a good translation of what this will mean to regular users.

In a nutshell, you can now define a location as safe, and then your Lollipop phone won’t ask you to unlock it when you’re nearby—it’ll just let you straight in.

 

Apps vs. Websites – The ownership perspective

This topic has been covered time and time again. Typically, these articles cover a mix of technology, performance, ROI, look and feel, and other such metrics.

Today I’m going to suggest that the end user’s ownership of an app (as opposed to a website) is one criteria that businesses should consider when making the decision to build a Native App. I’m also proposing that building a Responsive Website is no longer an option, but an expectation.

In 2014, even the cheapest smartphones come with HTML5 capable browsers! End users do not and should not have to understand why a website is different, and sometimes even feels alien, when viewed on a mobile device. The time when we had to compromise on mobile because of technical reasons is long gone. Let’s leave this here.

If the mobile browsing experience is in the same class as the browser experience then why should you even consider an app?

Unless you’re planning to build an amazing app that you plan to support long term, keep up to date with the fast evolving mobile UI/UX, in which you utilise the mobile platform paradigms to the point that the user feels like it was built in collaboration with the designers of the first party apps, then you probably shouldn’t build an app.

The subtlety here is that it all boils down to the fact that you own your website, but the end user owns your app.

If the user has a bad experience on your site, they can’t get rid of your mobile optimised (hopefully responsive) website. Your links will always work, even if they remove all shortcuts or bookmarks. A short url, a web search result or an ad will always be able to bring them back. When they’re back you’ll have a chance to make them change their mind and convince them to return in the future.

On the other hand, if the user has a bad experience with your app, they can simply forget the app ever existed on their device. They will delete it and they’ll do that almost as a punishment for your failure to delight them. Deleting the app will close all the communication channels once provided by that medium: all extensions and widgets will be gone, all URL schemes will seize to function. The reality is your app is competing with potential photos of their friends and family, or with another app that is more in fashion than yours.

The end user owns your app because they install it, they dedicate disk space to it, and they can get rid of it if they choose to. They are in complete control of this lifecycle and, you may not realise this, this lifecycle has financial and psychological implications.

Unlike accessing your website, when installing your app the user is likely to be asked for their password (or fingerprint for Touch ID). Even if your app is free, the psychological connection is made: they acquired your app. They are now using disk space just to have your app around.

Your app must be delightful, it must add value every time it’s used, otherwise the user will eventually run out of patience and delete it. Once they do, you will face a big uphill battle to convince them to give your app another try.

There is no such psychological attachment to your website because the user is not involved in the site’s lifecycle. They usually just “ask” a search engine for it. When they run out of space for their next photo they won’t think which sites they can remove…

If you can’t build a delightful mobile app, then you’d better have an amazing responsive website. The reality is though, that if you don’t have both, then it’s likely that you’ll never be the first port of call for a mobile user.