Motivation

To give credit where it’s due, the Starbucks app is great. I use it (at a minimum) once per day. It has everything I look for in a great mobile experience — coffee, fire 80’s Spotify playlists, and a lack of interaction with other people. I’m clearly not alone in these desires, as 20% of Starbucks transactions in the US are now made using mobile phones.

From Slack integrations to coffee buttons, there are loads of potential integrations that could be built if they opened their API to third-party developers. They’re clearly moving in that direction, as they have both a twitter account and a (password protected) website for developers.

I couldn’t wait, however, so I decided to take matters into my own hands.

They Didn’t Make It Easy

As it turns out, the Starbucks app is a tough nut to crack. Despite the URL being “openapi.starbucks.com,” there are quite a few obscure hoops to jump through before one can even begin analyzing the calls the app makes. As should be the case with any app that processes payments, Starbucks has taken many security measures to secure the APIs their app uses from unauthorized use. Here are some of them:

SSL certificate pinning

Fingerprinting attributes of your mobile phone to see if it’s “phonelike”

Encrypting that fingerprint using AES, with a 256-bit key and a random initialization vector

Signing requests with the current timestamp

Observing Network Requests

First things first, I needed a way to observe the requests and responses between the Starbucks app and their servers. Normally, I’d just point my iPhone at Charles (or mitmproxy) and I’d be on my way.

Not this time! Since the app uses certificate pinning, I wasn’t able to intercept any of the requests as I normally would. Instead, I had to dig up an old Android phone, root it, install a framework called Xposed, and finally install an extension that injects itself in running applications and disables SSL pinning.